Android-Java 和 JavaScript 相互調用

當前的Android開發中,會使用大量的h5(html5+css+js),甚至出現了混合開發模式(Hybrid),使用Hybrid開發,h5頁面開發效率高和移植便利性爲主。
但在一些地方使用h5開發的確會不太容易實現,這個時候就須要調用Java原生方法來完成,就會遇到JavasSript和Java相互調用,用Java原生方法實現那些Javascript代碼不容易實現的功能,好比,異步線程,調用數據庫等..... 而後再暴露給JavaScript調用。javascript

JavascriptInterface

Android 4.2以前使用addjavascriptinterface能夠把原生的Java方法,給JavaScript調用,可是這種方案卻存在安全風險,在頁面中執行一些不可信的Javascript代碼即有可能控制用戶的手機,詳情見:WebView中接口隱患與手機掛馬利用
Android 4.2以後提供了@JavascriptInterface對象註解的方式創建Javascript對象和android原生對象的綁定,提供給JavaScript調用的方法必須帶有@JavascriptInterface
當前4.0及4.0以前的系統市場佔有量已經很低了,所以能夠考慮使用minSdkVersion爲17,只支持4.2版本以上的手機,低版本的系統再也不支持了。
下面就看下Java和Javascript是如何通訊的。css

加載本地html

爲了方便使用,下面使用的示例,不會使用server,因此就須要在webview中使用本地的html文件,爲了方便把html文件都放在assets文件夾中,使用本地加載的方式,這樣就不須要服務器的支持了。
先定義一個html文件:html

<!DOCTYPE html>
<html> <body> <h1>this is html</h1> </body> </html>複製代碼

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

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

下面就能夠在index.html中試用Java和JavaScript的調用了。java

Javascript調用Java方法

以Android的Toast的爲例,下面看下如何從Javascript代碼中調用系統的Toast
先定義一個AndroidToast的Java類,它有一個show的方法用來顯示Toast:android

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

再對WebView進行設置,開啓JavaScipt,註冊JavascriptInterface的方法:git

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中的方法了。
在Javascript中調用Java代碼:github

function toastClick(){
        window.AndroidToast.show('from js');
}複製代碼

經過window屬性能夠找到映射的對象AndroidToast,直接調用它的show方法便可。
注意這裏傳輸的數據只能是基本數據類型和string,能夠傳輸string就意味着可使用json傳輸結構化數據。
這裏調用的方法並無返回值,若是須要在JavaScript中須要獲得返回值怎麼辦呢?web

JavaScript調用Java有返回值

若是想從Javascript調的方法裏面獲取到返回值,只須要定義一個帶返回值的@JavascriptInterface方法便可:數據庫

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

添加Javascript的映射:

webView.addJavascriptInterface(new AndroidMessage(), "AndroidMessage");複製代碼

在JavaScript直接調用:

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

這樣就完成了有返回值的方法調用。還有一種場景是,在Java中主動觸發JavaScript方法,就須要在Java中調用JavaScript方法了。

Java調用JavaScript方法

Java在調用JavaScript方法的時候,須要使用WebView.loadUrl()方法,它能夠直接在頁面裏執行JavaScript方法。
首先定義一個JavaScript方法給Java調用:

function callFromJava(str){
        console.log(str);
    }複製代碼

在Java中直接調用該方法:

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

能夠在loadUrl中給Javascript方法直接傳參,若是JavaScript方法有返回值,使用WebView.loadUrl()是沒法獲取到返回值的,須要JavaScript返回值給Java的話,能夠定義一個Java方法提供給JavaScript調用,而後Java調用JavaScript以後,JavaScript觸發該方法把返回值再傳遞給Java。
注意WebView.loadUrl()必須在Ui線程中運行,否則會會報錯。

項目地址:github.com/jjz/android…

相關文章
相關標籤/搜索