1. 程式人生 > >Android筆記之 Webview與Js互動-詳情舉例

Android筆記之 Webview與Js互動-詳情舉例

Android呼叫網頁自身Js

你好! 這是你第一次使用 Markdown編輯器 所展示的歡迎頁。如果你想學習如何使用Markdown編輯器, 可以仔細閱讀這篇文章,瞭解一下Markdown的基本語法知識。 本地(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的方法會用到。

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的佈局樣式等。