Android笔记之 Webview与Js交互-详情举例

Android调用网页自身Js

本地(asset)网页androidcalljs.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>android调用js</title>
    <script>
    function JsSelf(){
	  document.getElementById("demo").innerHTML="网页自身调用JS";
}
	function JsUseEvaluateJavascript(){
	 document.getElementById("demo2").innerHTML="Android调用网页自身Js UseEvaluateJavascript";
	 return "Android调用网页自身Js UseEvaluateJavascript";
}
	function JsUseLoadUrl(){
	  document.getElementById("demo1").innerHTML="Android调用网页自身Js UseLoadUrl";
}
    </script>
</head>
<body>
<h1>android调用js</h1>
<p id="demo">网页调用js</p>
<p id="demo1">调用js loadUrl</p>
<p id="demo2">调用js useEvaluateJavascript</p>
<button type="button" onclick="JsSelf()">网页自身调用JS</button>
</body>
</html>

上面网页自身包含3个JavaScript函数

1、“loadUrl”调用网页自身js

        String script = "javascript:JsUseLoadUrl()";
        mWebView.loadUrl(script);

以上代码中JsUseLoadUrl()对应的是网页自身JavaScript里面的function函数。

2、“evaluateJavascript”调用网页自身js

   String script = "javascript:JsUseEvaluateJavascript()";
   mWebView.evaluateJavascript(script, new ValueCallback<String>() {
        @Override
        public void onReceiveValue(String value) {
            //value的值为 JavaScript执行 JsUseEvaluateJavascript()方法后的返回值
            //即 “Android调用网页自身Js UseEvaluateJavascript”
             Log.e(TAG,value);
        }
   });

同理,以上代码中JsUseEvaluateJavascript()对应的是网页自身JavaScript里面的function函数。
这里注意的是“evaluateJavascript”的参数列表,第一个参数是要执行的js,第二个则是Js函数执行后如果带有返回值,这里将在onReceiveValue方法中接收该值,同时注意该值类型为String

3、区别

loadUrl不带返回值,会刷新界面;
evaluateJavascript带返回值,不会刷新界面,但需要API 19以后使用。

Android注入Js并调用

loadUrl

       String script = "javascript:(function(){" +
                "document.getElementById(\"demo1\").innerHTML=\"Android注入Js并调用 UseLoadUrl\";" +
                "}())";
        mWebView.loadUrl(script);

evaluateJavascript

        String script = "javascript:(function(){" +
                "document.getElementById(\"demo2\").innerHTML=\"Android调用外部Js useEvaluateJavascriptOut\";" +
                "return \"Android调用外部Js useEvaluateJavascriptOut\";}())";
        mWebView.evaluateJavascript(script, new ValueCallback<String>() {
            @Override
            public void onReceiveValue(String value) {
            }
        });

两种注入JS没有区别,需要注意的是注入的JavaScript格式:

        "javascript:(function(){" +
                   //TODO 注意圆括号 花括号
        "}())";

Js调用Android方法

JavaScript调用Android方法的HTML文件

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>js调用android</title>
    <script>
	function JsUseEvaluateJavascript(text){
	 document.getElementById("withparms").innerHTML="js调用android带参成功 android返回的值是:"+text;
	 return "Android调用Js UseEvaluateJavascript";
    }
	function JsUseLoadUrl(){
	  document.getElementById("noparm").innerHTML="js调用android方法成功 android调用js";
    }
    function callAndroidnoParms(){
	    android.callAndroidnoParms();
    }
    </script>
</head>
<body>
<h1>js调用android</h1>
<p id="withparms">等待android反馈</p>
<p id="noparm">等待android反馈</p>
<button type="button" onclick="callAndroidnoParms()">JS调用android方法</button>
<button type="button" onclick="window.android.callAndroidwithParms('我是参数')">JS带参数调用android方法
</button>
</body>
</html>

webview.addJavascriptInterface(object,String)

1、在Activity中的需要被调用的方法添加注解@JavascriptInterface

    @JavascriptInterface
    public void callAndroidnoParms() {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {     
                String script = "javascript:JsUseLoadUrl()";
                mWebView.loadUrl(script);
            }
        });
    }

上面方法callAndroidnoParms是要被JavaScript调用的方法,调用成功之后,run方法里面再从Android这边调用Js。

注意

上面调用callAndroidnoParms成功之后,如果要对webview做其他操作,必须要和生成webview的线程在同一线程中,比如在主线程实例化的webview,这里就要使用runOnUiThread,否则会报错(不会引起程序崩溃)
java.lang.RuntimeException: java.lang.Throwable: A WebView method was called on thread 'JavaBridge'. All WebView methods must be called on the same thread. (Expected Looper Looper (main, tid 1) {4a7b4bb0} called on Looper (JavaBridge, tid 76) {4a7ba6d0}, FYI main Looper is Looper (main, tid 1) {4a7b4bb0})

2、mWebView.addJavascriptInterface(object, String);

使用addJavascriptInterface方法,其中object参数是映射成JavaScript的对象,String是给该映射对象取的别名。

比如 mWebView.addJavascriptInterface(this, "android");该句话的意思就是把当前对象(Activity)映射成JavaScript的对象,android就是对该映射对象取的别名,该别名在JavaScript调用Activity的方法会用到。

也可以自定义类来把需要调用的方法封装起来,其实和Activity差不多,只是在第一个参数那里有点区别,需要new。

   public class JsCallAndroid {
        @JavascriptInterface
        public void callAndroidnoParms() {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    String script = "javascript:JsUseLoadUrl()";
                    mWebView.loadUrl(script);
                }
            });
        }
   }

调用的时候:

 mWebView.addJavascriptInterface(new JsCallAndroid(), "android");

3、JavaScript调用

    <!--JavaScript标签里面的方法-->
     function callAndroidnoParms(){
	     android.callAndroidnoParms();
     }
 <!--body标签里面的按钮-->
<button type="button" onclick="callAndroidnoParms()">JS调用android方法</button>

上面android.callAndroidnoParms()意思就是执行android别名(Activity)里面的callAndroidnoParms()方法,也就是上面 第1点添加注解的那个方法。

还有一种方式就是

 <!--body标签里面的按钮-->
<button type="button" onclick="window.android.callAndroidwithParms('我是参数')">JS带参数调用android方法
</button>

在Activity里面

@JavascriptInterface
    public void callAndroidwithParms(final String text) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                //这里text的值=“我是参数” 即HTML网页里面传递过来的
                String script = "javascript:JsUseEvaluateJavascript('" + text + "')";
                //android调用js
                mWebView.evaluateJavascript(script, new ValueCallback<String>() {
                    @Override
                    public void onReceiveValue(String value) {
                        //value的值=Android调用Js UseEvaluateJavascript
                    }
                });
            }
        });
    }

上面是调用带有参数的方法,使用的方式是window.android.callAndroidwithParms('我是参数')

当然上面调用不带参数的方法,即上面callAndroidnoParms方法,也可以使用window.android.callAndroidnoParms()方式

<button type="button" onclick="window.android.callAndroidnoParms()">JS调用android方法</button>

网上还有其他方式,即监听webview的某些方法,拦截处理,来实现android与js之间的交互,比如:shouldOverrideUrlLoading,onPageFinished,onProgressChanged,onJsAlert,onJsConfirm等等。
通常是在onProgressChanged或者onPageFinished方法里面注入js,修改原HTML的布局样式等。

本笔记Android Studio代码

猜你喜欢

转载自blog.csdn.net/wyl_tyrael/article/details/83383837
今日推荐