1. 程式人生 > >Android原生方法和Web JS互相呼叫

Android原生方法和Web JS互相呼叫

準備工作

  1. 新建一個Android專案
  2. 準備一個html檔案,為了簡化,直接放到專案的assets目錄下呼叫

JS呼叫Android原生方法

在Android專案中

配置WebView,WebView的配置中必須啟用JavaScript,新增JavaScript的入口介面,方法如下:
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new H5Interface(MainActivity.this, webView), "h5_android");

在html檔案中

新增JavaScript程式碼 在JavaScript中呼叫Android本地介面的格式是“本地JavaScript介面名稱.介面方法名稱”,介面名稱是Android WebView呼叫addJavascriptInterface方法時的第二個引數,方法如下:
h5_android.login(platform, extInfo);

Android原生方法呼叫JS

在html中

新增JavaScript程式碼,編寫一個JavaScript方法


在Android專案中

在開啟當前頁面的WebView物件,呼叫loadUrl方法執行JavaScript方法,URL格式為"javascript:JavaScript方法名()",但必須注意的是,如果JavaScript方法的引數是字串,必須新增單引號將內容括起來,否則會當做一個物件,方法如下:
mmWebView.loadUrl(String.format("javascript:onLoginResult('%s')", "登入取消"));
注意:呼叫loadUrl的WebView物件必須是開啟當前頁面的WebView


本地JavaScript呼叫入口類程式碼如下:
class H5Interface {

    private Activity mmActivity;
    private WebView mmWebView;

    public H5Interface(Activity activity, WebView webView) {
        this.mmActivity = activity;
        this.mmWebView = webView;
    }

    @JavascriptInterface
    public void login(String platform, String extInfo) {
        mmActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                WAUserProxy.loginUI(mmActivity, false, new WACallback<WALoginResult>() {
                    @Override
                    public void onSuccess(int i, String s, WALoginResult waLoginResult) {
                        mmWebView.loadUrl(String.format("javascript:onLoginResult('%s')", new Gson().toJson(waLoginResult)));
                    }

                    @Override
                    public void onCancel() {
                        mmWebView.loadUrl(String.format("javascript:onLoginResult('%s')", "登入取消"));
                    }

                    @Override
                    public void onError(int i, String s, WALoginResult waLoginResult, Throwable throwable) {
                        mmWebView.loadUrl(String.format("javascript:onLoginResult('登入失敗:\ncode: %d\n message: %s')", i, s));
                    }
                });
            }
        });
    }
}
上面程式碼中可以看到,H5Interface類中有一個login成員方法,這個方法就是在html頁面的JavaScript中呼叫的。注意:開放給JavaScript呼叫的方法必須新增@JavascriptInterface註解,在 JELLY_BEAN/API 16/4.1開始必須新增,否則JavaScript無法呼叫到這個介面 html程式碼如下
<!DOCTYPE html>
<html>
<head>
    <script type="text/javascript">
        function login(platform, extInfo) {
            h5_android.login(platform, extInfo);
        }

        function onLoginResult(result) {
            document.getElementById("messageArea").textContent = result
        }
    </script>
</head>
<body>
    <h1 align="center">Android與JS互調示例</h1>

    <h2>JS呼叫Android原生功能</h2>
    <input type="button"
           style="width:100%; font-size: 25px"
           value="登入"
           onClick="login('', '')"/>

    <h2>Android呼叫JS</h2>
    <div style="font-size: 25px">登入結果:</div>
    <div style="width: 100%">
        <textarea id="messageArea" rows="10" style="width: 100%; font-size: 25px"></textarea>
    </div>
</body>
</html>
特別注意:JS執行的程式碼不在Android的UI執行緒中,是在WebView Core的執行緒中,所以JS呼叫Android的介面中,需要新增到Activity.runOnUiThread中