android webview js

在當前的Android開發中,會使用大量的H5(html5+css3+js),和Native一起的混合開發模式(Hybrid),在Hybrid開發的過程中,H5部分開發效率高和移植便利性爲主,但是在一些地方使用h5的確不容易實現,這個時候就需要調用Java方法來完成某些功能,就會遇到Javascript和Java相互調用,用Java的方法實現那些Javascript代碼不容易,不好完成的任務,比如,異步線程,調用數據庫等.....

在Android 4.2之前可以使用addjavascriptinterface的方式注入原生的Java中,給JavaScript調用,但是這種方案卻會有一定的安全風險,在頁面中執行一些不可信的Javascript代碼即可能控制用戶的手機,詳情見:WebView中接口隱患與手機掛馬利用
在4.2之後Android提供了@JavascriptInterface對象註解的方式建立Javascript對象和android原生對象的綁定,提供給javascript調用的函數必須帶有@JavascriptInterface

因爲目前4.0系統的手機市場佔有量已經很低了,因此我們使用minSdkVersion爲17,只需要支持4.2版本以上的手機,看下Java和Javascript怎麼通信的。

加載本地html文件

有的時候我們在使用webview開發的時候會使用本地的html文件,在這裏爲了方便我們把html文件都放在assets文件夾中,使用本地加載的方式,不需要server支持。
先定義一個html文件:

<!DOCTYPE html>
<html>
    <body>
        <h1>this is html</h1>
    </body>
</html>

使用file:///android_asset/index.html加載到webview中:

    private void initView() {
        webView = (WebView) findViewById(R.id.webView);
        webView.loadUrl("file:///android_asset/index.html");
    }

Javascript調用Java方法

以Android的Toast的爲例,從Javascript代碼中調用系統的Toast。
我們定義一個AndroidToast的Java類,它有一個show的方法用來顯示Toast:

public class AndroidToast {
        @JavascriptInterface
        public void show(String str) {
            Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();
        }
    }

需要對WebView設置一些參數,開啓JavaScipt,註冊JavascriptInterface:

private void initView() {
        webView = (WebView) findViewById(R.id.webView);

        WebSettings webSettings = webView.getSettings();
        webSettings.setJavaScriptEnabled(true);
        webSettings.setDefaultTextEncodingName("UTF-8");
        webView.addJavascriptInterface(new AndroidToast(), "AndroidToast");
        webView.loadUrl("file:///android_asset/index.html");
 }

addJavascriptInterface的作用是把AndroidToast類映射爲Javascript中的AndroidToast對象。

在Javascript中調用Java代碼:

function toastClick(){
        window.AndroidToast.show('from js');
}

通過window的屬性可以找到Java映射的對象AndroidToast,調用它的show方法。
注意這裏傳輸的數據只能是基本數據類型和string,可以傳輸string意味着我們可以使用json傳輸結構化數據。

Javascript調用Java有返回值

如果想從Javascript調的方法裏面獲取到返回值,只需要定義一個帶返回值的@JavascriptInterface方法:


    public class AndroidMessage {
        @JavascriptInterface
        public String getMsg() {
            return "form java";
        }
    }

添加Javascript的映射Webview:

webView.addJavascriptInterface(new AndroidMessage(), "AndroidMessage");

Javascript直接調用Java方法:

function showAlert(){
        var str=window.AndroidMessage.getMsg();
        console.log(str);
 }

Java調用Javascript方法

Java在調用js的時候,使用的是WebView.loadUrl()方法,可以直接在HTML頁面裏面執行JavaScript方法,首先定義一個Javascript方法給Java調用:

function callFromJava(str){
        console.log(str);
    }

Java端調用Javascript方法:

public void  javaCallJS(){
        webView.loadUrl("javascript:callFromJava('call from java')");
    }

可以在loadUrl中直接給Javascript方法直接傳值,如果Javascript方法有返回值,而WebView.loadUrl()是無法獲取到返回值的,如果需要Javascript返回值給Java,可以定義一個Java方法給JavaScript調用把返回值傳遞給Java。
注意WebView.loadUrl()必須在Ui線程中運行,不然會會報錯。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章