Android小知识-WebView的Java和JavaScript交互

宋典
2023-12-01

本平台的文章更新会有延迟,大家可以关注微信公众号-顾林海,包括年底前会更新kotlin由浅入深系列教程,目前计划在微信公众号进行首发,如果大家想获取最新教程,请关注微信公众

目前市面上的大部分APP都是混合开发,也就是大家所说的Hybrid方式,集成了Native和Web的优点,使用native可以保证用户的体验,使用Web可以使得APP具有动态更新的能力,同时有利于跨平台开发,节省人力物力。平时在使用Hybrid时主要就是实现Java和JavaScript的交互。

例子一:Java调用JavaScript

首先我们创建一个toJavaScript.htm的文件,并复制到工程的assets目录下,在toJavaScript.html文件中填写以下内容:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
</head>
这是html
<script language="javascript">

    function showToast(){
        alert("Java调用JavaScript");
    }

</script>
</html>
复制代码

html文件中很简单,只定义了一个showToast方法,执行该方法会弹出一个框。

接着我们在MainActivity中添加调用JavaScript方法的代码:

        mWebView = findViewById(R.id.wv_web_view);
        WebSettings settings = mWebView.getSettings();
        //使用JavaScript
        settings.setJavaScriptEnabled(true);
        mWebView.setWebChromeClient(new WebChromeClient());
        mWebView.loadUrl("file:///android_asset/toJavaScript.html");
        Button buttonGet = findViewById(R.id.btn_get);
        buttonGet.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mWebView.loadUrl("javascript:showToast()");
            }
        });
复制代码

点击按钮会调用showToast方法并显示弹框。

例子二:JavaScript调用Java

实现JavaScript调用Java方式,我们可以按照以下三步骤:

  1. 调用与WebView关联的WebSettings实例的setJavaScriptEnabled方法来使用JavaScript脚本调用的功能。

  2. 调用WebView的addJavascriptInterface方法将应用的Java对象暴露给JavaScript。

  3. 在JavaScript中调用步骤二暴露出来的Java对象的方法。

暴露给JavaScript的Java对象如下:

package com.apk.administrator.loadapk;

import android.webkit.JavascriptInterface;

public class JavaBean {

    private HtmlCallback mCallback;

    JavaBean(HtmlCallback callback){
        this.mCallback=callback;
    }

    @JavascriptInterface
    public void setName(String name){
        if(mCallback!=null){
            mCallback.name(name);
        }
    }

    public interface HtmlCallback{

        void name(String name);

    }

}
复制代码

在JavaScript调用JavaBean对象的setName方法时提供了一个回调。

接着在MainActivity中初始化我们的WebView:

    private void initWebView(){
        mWebView = findViewById(R.id.wv_web_view);
        WebSettings settings=mWebView.getSettings();
        settings.setJavaScriptEnabled(true);
        mWebView.setWebChromeClient(new WebChromeClient());
        mWebView.loadUrl("file:///android_asset/toJava.html");
        mJavaBean=new JavaBean(new JavaBean.HtmlCallback() {
            @Override
            public void name(String name) {
                Toast.makeText(MainActivity.this,name,Toast.LENGTH_SHORT).show();
            }
        });
        mWebView.addJavascriptInterface(mJavaBean,"javaBean");
    }
复制代码

最后就是toJava.html文件了:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
</head>
    <input type="button" value="设置姓名" onclick="javaBean.setName('顾林海');" />
</html>
复制代码

Html页面上就只有一个按钮,点击按钮调用JavaBean的setName方法并把参数传递过去。点击的同时,APP显示一个Toast。

在Android4.2之前还没有@JavascriptInterface注解,这样的话会引起臭名昭著的WebView远程代码执行漏洞,从Android4.2开始,Google修复了这个漏洞,就是在暴露给JavaScript调用的Java对象的方法上添加@JavascriptInterface注解。

如果为了兼容Android4.2以下的版本,就不要再使用addJavascriptInterface这种方式,可以通过Android的WebChromeClient类,其中onJsPrompt方法会传递过来一个String类型的字符串,APP端和Web端约定好协议,通过该方法完成JavaScript调用Java方法。


搜索微信“顾林海”公众号,定期推送优质文章。

 类似资料: