Android webview 與 js(Vue) 交互


js 與原生交互分為兩種情況:js 調用原生方法,原生調用 js 方法。

本文將對這兩種情況分別講解,H5 端用 vue 實現。

一、前期准備(Vue項目准備)

本文的 H5 端用Vue 實現,所以在正式開始前先把 Vue 項目環境准備好。

項目寫好后,執行 npm run serve 命令啟動項目,啟動成功后會在命令行看到兩個地址:

 

 

http://localhost:8080/http://10.0.0.188:8080/

10.0.0.188 是我本機的 ip 地址,每個人的不一樣。

在電腦的瀏覽器訪問的話哪個都行,但在手機或模擬器訪問的話需要用第二個帶 ip 地址的,且要保證手機跟電腦連接同一個 wifi 或在同一網段。

啟動成功后在 Android 項目中將  http://10.0.0.188:8080/ 地址配置給  WebView 即可
Intent intent = new Intent(getActivity(), ProgressWebviewActivity.class);
intent.putExtra("url", "http://10.0.0.188:8080/");
startActivity(intent);

到此,在手機中就可以訪問 Vue 項目了。

二、Android 原生調用 JS 中的方法

Android 調用 JS 有兩種方式,都是通過 WebView 的方法:

  1. webview.loadUrl()
  2. webview.evaluateJavascript()

二者區別:

  1. loadUrl() 會刷新頁面,evaluateJavascript() 則不會使頁面刷新,所以 evaluateJavascript() 的效率更高

  2. loadUrl() 得不到 js 的返回值,evaluateJavascript() 可以獲取返回值

  3. evaluateJavascript() 在 Android 4.4 之后才可以使用

要實現的效果:

如下圖,頁面上有一行文字 ”哈哈“,要在 WebView 頁面加載完的時候通過 Android 原生代碼將這行字改為 ”我通過原生方法改變了文字“ + Android 傳遞過來的參數,並給 Android 返回一個字符串 ”js調用成功“。

 

 

2.1 Vue 代碼

先看 Vue 中代碼怎么寫

mounted() {
    //將要給原生調用的方法掛載到 window 上面
    window.callJsFunction = this.callJsFunction
},
data() {
    return {
        msg: "哈哈"
    }
},
methods: {
    callJsFunction(str) {
        this.msg = "我通過原生方法改變了文字" + str
        return "js調用成功"
    }
}

methods 中定義一個供 Android 調用的方法 callJsFunction(str) , 並可接收一個參數 str,然后改變頁面中的文字。

如果只是在 methods 中定義方法,原生調用會找不到這個方法。所以要在頁面加載的時候將方法掛載在 window 上,這樣 WebView 就可以拿到此方法了。注意,這步很重要一定要寫!

注意一個細節,this.callJsFunction 后面不要加括號 (),加括號相當於直接調用了。

總結起來 Vue 中要做的事情就兩步:

  1. methods 中定義方法
  2. mounted 中將方法掛載在 window

2.2 Android 中代碼

需要等頁面加載完在 WebViewonPageFinished 方法中寫調用邏輯,否則不會執行。

2.2.1 loadUrl() 實現

tbsWebView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url, headerMap);
                return true;
            }

            @Override
            public void onPageFinished(WebView webView, String s) {
                super.onPageFinished(webView, s);
                //安卓調用js方法。注意需要在 onPageFinished 回調里調用
                tbsWebView.post(new Runnable() {
                    @Override
                    public void run() {
                        tbsWebView.loadUrl("javascript:callJsFunction('soloname')");
                    }
                });
            }
        });
    }
});

如果不需要傳參數,把參數去掉即可 tbsWebView.loadUrl("javascript:callJsFunction()");

2.2.2 evaluateJavascript() 實現

其他地方跟loadUrl()一樣,只是把 tbsWebView.loadUrl("javascript:callJsFunction('soloname')"); 替換掉

@Override
public void onPageFinished(WebView webView, String s) {
    super.onPageFinished(webView, s);
    //安卓調用js方法。注意需要在 onPageFinished 回調里調用
    tbsWebView.post(new Runnable() {
        @Override
        public void run() {
            tbsWebView.evaluateJavascript("javascript:callJsFunction('soloname')", new ValueCallback<String>() {
                @Override
                public void onReceiveValue(String s) {
                    Logger.d("js返回的結果: " + s);
                }
            });
        }
    });
}

可以看到頁面更新了,第二種方法也拿到了返回的結果。

 

 

三、JS 調用 Android 原生方法

對於JS調用Android代碼的方法有3種:

  1. 通過 WebViewaddJavascriptInterface() 進行對象映射
  2. 通過 WebViewClientshouldOverrideUrlLoading()方法回調攔截 url
  3. 通過 WebChromeClientonJsAlert()onJsConfirm()onJsPrompt()方法回調攔截JS對話框alert()confirm()prompt() 消息

對比: 第一種最簡潔,但在 Android 4. 2 以下存在漏洞;第二種和第三種使用復雜,但不存在漏洞問題。

由於目前的設備系統版本基本都在 4.2 以上,所以用第一種就可以了,簡單快捷。時間有限本文只實現第一種,第二種和第三種就不實現了,想了解的可以參考 這篇文章

3.1 效果展示

要實現的效果就是點擊 H5 頁面上的按鈕,彈出 Android 原生的 Toast

 

 

3.2 Vue 代碼

methods: {
  showAndroidToast() {
    $App.showToast("哈哈,我是js調用的")
  }
}

在 methods 中定義方法 showAndroidToast() , 點擊頁面上按鈕 "調用Android原生Toast" 時調用。

3.3 Android 代碼

新建類 JsJavaBridge

public class JsJavaBridge {

    private Activity activity;
    private WebView webView;

    public JsJavaBridge(Activity activity, WebView webView) {
        this.activity = activity;
        this.webView = webView;
    }

    @JavascriptInterface
    public void onFinishActivity() {
        activity.finish();
    }

    @JavascriptInterface
    public void showToast(String msg) {
        ToastUtils.show(msg);
    }
}

然后通過 WebView 設置 Android 類與 JS 代碼的映射

tbsWebView.addJavascriptInterface(new JsJavaBridge(this, tbsWebView), "$App");

這里將類 JsJavaBridge 在 JS 中映射為了 $App,所以在 Vue 中可以這樣調用 $App.showToast("哈哈,我是js調用的")

以上就是 Android 與 JS 的互相調用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM