1. 程式人生 > >Android與JS互動篇--JSBridge的使用

Android與JS互動篇--JSBridge的使用

在android日常開發中,大家或多或少都會碰到原生巢狀web頁面,大家可以使用傳統的方式實現Native與JS的互動,這裡就不多介紹了,現在我們簡單介紹下網上目前比較流行的已經封裝好的框架JsBridge。

可參考官網github地址:點選開啟連結

先看下接下來將要實現的效果圖:

一、JsBridge的基本概念

Android4.4以前,谷歌的webview存在安全漏洞,網站可以通過js注入就可以隨便拿到客戶端的重要資訊,甚至輕而易舉的呼叫原生代碼進行流氓行為,谷歌在4.4以後增加了防禦措施,如果用js呼叫原生代碼,開發者必須在程式碼宣告JavascriptInterface, 4.4之前我們要使得webView載入js只需如下程式碼:

mWebView.addJavascriptInterface(new JsToJava(), “myfunction”);
4.4之後使用時, 需要在呼叫Java方法加入@JavascriptInterface註解,如果程式碼無此宣告,那麼js就不生效,這樣就可以避免惡意網頁利用js對客戶端的進行竊取和攻擊。 但使用比較繁瑣,要做一些判斷和限制,在比較複雜的Hybrid模式下,需要js和native之間進行互動通訊,原生的JavascriptInterface 難以維護,基於JavascriptInterface 封裝的WebViewJavascriptBridge框架,很好的解決了這一問題。

WebViewJavascriptBridge是移動UIView和Html互動通訊的橋樑,用於替代WebView自帶的JavascriptInterface介面,使開發者可以簡單安全的實現js和native互動。

二、以上圖為案例介紹JSBridge的使用方法

首先在Module的build.gradle裡引入JSBridge所需要的包,也可以下載原始碼引入專案自定義庫檔案

repositories {
    maven { url "https://jitpack.io" }
}

dependencies {
    ...
    compile 'com.github.lzyzsd:jsbridge:1.0.4'
}

在xml檔案中使用控制元件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center_horizontal"
    android:padding="20dp"
    android:background="#9f9f9f"
    tools:context="com.liuw.jsbridge.MainActivity">

    <EditText
        android:id="@+id/edit_view"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:background="#ffffff"
        android:gravity="top"
        android:textSize="14sp"
        android:textColor="@color/colorAccent"
        android:text="來自於js將要展示的資料"/>

    <Button
        android:id="@+id/btn_send"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:paddingLeft="10dp"
        android:paddingRight="10dp"
        android:layout_marginTop="10dp"
        android:text="傳送資料到webView"/>

    <Button
        android:id="@+id/btn_reset"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:paddingLeft="10dp"
        android:paddingRight="10dp"
        android:layout_marginTop="10dp"
        android:text="重置瀏覽器"/>

    <com.github.lzyzsd.jsbridge.BridgeWebView
        android:id="@+id/bridge_webview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="20dp">

    </com.github.lzyzsd.jsbridge.BridgeWebView>
</LinearLayout>

MainActivity主介面中使用

下面先簡單介紹下重點幾步操作:

1、載入網頁地址
mBridgeWebview.loadUrl("file:///android_asset/web.html");
2、註冊handler,接收來自js的資料data,並可通過onCallBack回傳資料
mBridgeWebview.registerHandler("submitFromWeb", new BridgeHandler() {
            @Override
            public void handler(String data, CallBackFunction function) {
                if (!TextUtils.isEmpty(data)) {
                    mEditText.setText("通過呼叫Native方法接收資料:\n" + data);
                }
                function.onCallBack("Native已經接收到資料:" + data + ",請確認!");
            }
        });

對應的js程式碼如下

function useClick() {
            var name = document.getElementById("uname").value;
            var pwd = document.getElementById("psw").value;
            var data = "name = " + name + ", password = " + pwd;

            window.WebViewJavascriptBridge.callHandler(
                'submitFromWeb', {'info':data},//data傳送給native
                function(responseData) {//接收onCallBack回傳回來的資料
                    document.getElementById("show").innerHTML = responseData;
                }
            );
     }

上面這種方法是通過native和js定義相同的標識進行通訊,還有種方法可直接在js中通過send方法傳送,並在native中建立DefaultHandler接收

mBridgeWebview.setDefaultHandler(new DefaultHandler(){
            @Override
            public void handler(String data, CallBackFunction function) {
                function.onCallBack("Native已收到訊息!");
            }
        });

對應js程式碼如下:

//h5直接通過send向Native傳送訊息,在DefaultHandler的handler方法裡接收,並可通過onCallBack方法回傳
    function sendClick() {
        var name = document.getElementById("uname").value;
        var pwd = document.getElementById("psw").value;
        var data = "name = " + name + ", password = " + pwd;

        window.WebViewJavascriptBridge.send(
            data,
            function(responseData) {
                document.getElementById("show").innerHTML = responseData
            }
        );
    }
3、定義callHandler,多用於在初始化介面時native向js傳送資料渲染介面,同時也可獲取來自js的資料
mBridgeWebview.callHandler("functionInJs", new Gson().toJson(new UserInfo("liuw", "123456")), new CallBackFunction() {
            @Override
            public void onCallBack(String data) {
                mEditText.setText("向h5傳送初始化資料成功,接收h5返回值為:\n" + data);
            }
        });

對應的js程式碼如下

function connectWebViewJavascriptBridge(callback) {
            if (window.WebViewJavascriptBridge) {
                callback(WebViewJavascriptBridge)
            } else {
                document.addEventListener(
                    'WebViewJavascriptBridgeReady'
                    , function() {
                        callback(WebViewJavascriptBridge)
                    },
                    false
                );
            }
        }

// 第一連線時初始化bridage
connectWebViewJavascriptBridge(function(bridge) {
            //註冊handler等待java程式碼呼叫
            //初始化時獲取資料是呼叫此處程式碼
            //引數:標識,要傳遞到JAVA的資料,回撥方法。
            //JAVA程式碼響應的方法:mBridgeWebview.callHandler("functionInJs", new Gson().toJson(實體類物件), new CallBackFunction(){onCallBack(String data)}
            bridge.registerHandler("functionInJs", function(data, responseCallback) {
                document.getElementById("show").innerHTML = ("data from Java: = " + data);
                var responseData = "I am javascript, Data reception success!";
                responseCallback(responseData);
            });
})
4、Native中send方法的使用
這裡需要注意下,該方法對應js中的bridge.init處理,此處需加CallBackFunction方法,如果只使用mBridgeWebview.send("");如:mBridgeWebview.send("hello");,會導致js中只收到通知,接收不到值
mBridgeWebview.send("來自java的傳送訊息!!!", new CallBackFunction() {
            @Override
            public void onCallBack(String data) {
                Toast.makeText(MainActivity.this, "bridge.init初始化資料成功" + data, Toast.LENGTH_SHORT).show();
            }
        });

對應的js程式碼如下

function connectWebViewJavascriptBridge(callback) {
            if (window.WebViewJavascriptBridge) {
                callback(WebViewJavascriptBridge)
            } else {
                document.addEventListener(
                    'WebViewJavascriptBridgeReady'
                    , function() {
                        callback(WebViewJavascriptBridge)
                    },
                    false
                );
            }
        }

    // 第一連線時初始化bridage
    connectWebViewJavascriptBridge(function(bridge) {
            //也註冊預設的Handler,用來接收java呼叫的send(string,CallBackFunction)方法
            bridge.init(function(message, responseCallback) {
                console.log('JS got a message', message);
                var data = {
                    'Javascript Responds': '測試中文!'
                };
                console.log('JS responding with', data);
                responseCallback(data);
            });
    })
5、再介紹一種常規的Native直接向js傳遞資料的方法
//直接呼叫nativeFunction方法向H5傳送資料
mBridgeWebview.loadUrl("javascript:nativeFunction('" + data + "')");

對應的js程式碼如下

    function nativeFunction(data) {
        document.getElementById("show").innerHTML = data;
    }

只需通過方法名直接呼叫即可,是不是很簡單啊~

三、下面上完整程式碼

package com.liuw.jsbridge;

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.ClipData;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.github.lzyzsd.jsbridge.BridgeHandler;
import com.github.lzyzsd.jsbridge.BridgeWebView;
import com.github.lzyzsd.jsbridge.CallBackFunction;
import com.github.lzyzsd.jsbridge.DefaultHandler;
import com.google.gson.Gson;
import com.liuw.jsbridge.bean.UserInfo;

import butterknife.ButterKnife;
import butterknife.InjectView;

public class MainActivity extends AppCompatActivity {

    @InjectView(R.id.edit_view)
    EditText mEditText;
    @InjectView(R.id.btn_send)
    Button btnSend;
    @InjectView(R.id.bridge_webview)
    BridgeWebView mBridgeWebview;
    @InjectView(R.id.btn_reset)
    Button btnReset;

    private String TAG = "MainActivity";
    private MyHandlerCallBack.OnSendDataListener mOnSendDataListener;
    private ValueCallback<Uri> mUploadMessage;
    ;
    private ValueCallback<Uri[]> mUploadCallbackAboveL;
    private final static int FILECHOOSER_RESULTCODE = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.inject(this);

        initListener();
        initWebView();
    }

    private void initWebView() {
        //輔助WebView設定處理關於頁面跳轉,頁面請求等操作
        mBridgeWebview.setWebViewClient(new MyWebViewClient(mBridgeWebview, MainActivity.this));
        //Handler做為通訊橋樑的作用,接收處理來自H5資料及回傳Native資料的處理,當h5呼叫send()傳送訊息的時候,呼叫MyHandlerCallBack
        mBridgeWebview.setDefaultHandler(new MyHandlerCallBack(mOnSendDataListener));
        //WebChromeClient主要輔助WebView處理Javascript的對話方塊、網站圖示、網站title、載入進度等比等,不過它還能處理檔案上傳操作
        mBridgeWebview.setWebChromeClient(new MyChromeWebClient());
        // 如果不加這一行,當點選介面連結,跳轉到外部時,會出現net::ERR_CACHE_MISS錯誤
        // 需要在androidManifest.xml檔案中宣告聯網許可權
        // <uses-permission android:name="android.permission.INTERNET"/>
        if (Build.VERSION.SDK_INT >= 19) {
            mBridgeWebview.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
        }

        //載入網頁地址
        mBridgeWebview.loadUrl("file:///android_asset/web.html");

        //有方法名的都需要註冊Handler後使用
        mBridgeWebview.registerHandler("submitFromWeb", new BridgeHandler() {
            @Override
            public void handler(String data, CallBackFunction function) {
                Log.i("liuw", "html返回資料為:" + data);
                if (!TextUtils.isEmpty(data)) {
                    mEditText.setText("通過呼叫Native方法接收資料:\n" + data);
                }
                function.onCallBack("Native已經接收到資料:" + data + ",請確認!");
            }
        });

        mBridgeWebview.registerHandler("functionOpen", new BridgeHandler() {
            @Override
            public void handler(String data, CallBackFunction function) {
                Toast.makeText(MainActivity.this, "網頁在開啟你的檔案預覽", Toast.LENGTH_SHORT).show();
            }
        });

        //應用啟動後初始化資料呼叫,js處理方法connectWebViewJavascriptBridge(function(bridge)
        mBridgeWebview.callHandler("functionInJs", new Gson().toJson(new UserInfo("liuw", "123456")), new CallBackFunction() {
            @Override
            public void onCallBack(String data) {
                mEditText.setText("向h5傳送初始化資料成功,接收h5返回值為:\n" + data);
            }
        });

        //對應js中的bridge.init處理,此處需加CallBackFunction,如果只使用mBridgeWebview.send("");會導致js中只收到通知,接收不到值
        mBridgeWebview.send("來自java的傳送訊息!!!", new CallBackFunction() {
            @Override
            public void onCallBack(String data) {
                Toast.makeText(MainActivity.this, "bridge.init初始化資料成功" + data, Toast.LENGTH_SHORT).show();
            }
        });

    }

    private void initListener() {
        btnSend.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String data = mEditText.getText().toString();
                //直接呼叫nativeFunction方法向H5傳送資料
                mBridgeWebview.loadUrl("javascript:nativeFunction('" + data + "')");
            }
        });

        btnReset.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mBridgeWebview.loadUrl("file:///android_asset/web.html");
            }
        });

        mOnSendDataListener = new MyHandlerCallBack.OnSendDataListener() {
            @Override
            public void sendData(String data) {
                mEditText.setText("通過webview發訊息接收到資料:\n" + data);
            }
        };
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == FILECHOOSER_RESULTCODE) {
            if (null == mUploadMessage && null == mUploadCallbackAboveL) {
                return;
            }
            Uri result = data == null || resultCode != RESULT_OK ? null : data.getData();
            if (mUploadCallbackAboveL != null) {
                onActivityResultAboveL(requestCode, resultCode, data);
            } else if (mUploadMessage != null) {
                mUploadMessage.onReceiveValue(result);
                mUploadMessage = null;
            }
        }
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private void onActivityResultAboveL(int requestCode, int resultCode, Intent data) {
        if (requestCode != FILECHOOSER_RESULTCODE
                || mUploadCallbackAboveL == null) {
            return;
        }

        Uri[] results = null;
        if (resultCode == Activity.RESULT_OK) {
            if (data == null) {

            } else {
                String dataString = data.getDataString();
                ClipData clipData = data.getClipData();

                if (clipData != null) {
                    results = new Uri[clipData.getItemCount()];
                    for (int i = 0; i < clipData.getItemCount(); i++) {
                        ClipData.Item item = clipData.getItemAt(i);
                        results[i] = item.getUri();
                    }
                }

                if (dataString != null) {
                    results = new Uri[]{Uri.parse(dataString)};
                }
            }
        }
        mUploadCallbackAboveL.onReceiveValue(results);
        mUploadCallbackAboveL = null;
    }

    //自定義 WebChromeClient 輔助WebView處理圖片上傳操作【<input type=file> 檔案上傳標籤,點選會自動呼叫】
    public class MyChromeWebClient extends WebChromeClient {
        // For Android 3.0-
        public void openFileChooser(ValueCallback<Uri> uploadMsg) {
            Log.d(TAG, "openFileChoose(ValueCallback<Uri> uploadMsg)");
            mUploadMessage = uploadMsg;
            Intent i = new Intent(Intent.ACTION_GET_CONTENT);
            i.addCategory(Intent.CATEGORY_OPENABLE);
            i.setType("*/*");
            MainActivity.this.startActivityForResult(Intent.createChooser(i, "File Chooser"), FILECHOOSER_RESULTCODE);
        }

        // For Android 3.0+
        public void openFileChooser(ValueCallback uploadMsg, String acceptType) {
            Log.d(TAG, "openFileChoose( ValueCallback uploadMsg, String acceptType )");
            mUploadMessage = uploadMsg;
            Intent i = new Intent(Intent.ACTION_GET_CONTENT);
            i.addCategory(Intent.CATEGORY_OPENABLE);
            i.setType("*/*");
            MainActivity.this.startActivityForResult(
                    Intent.createChooser(i, "File Browser"),
                    FILECHOOSER_RESULTCODE);
        }

        //For Android 4.1
        public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
            Log.d(TAG, "openFileChoose(ValueCallback<Uri> uploadMsg, String acceptType, String capture)");
            mUploadMessage = uploadMsg;
            Intent i = new Intent(Intent.ACTION_GET_CONTENT);
            i.addCategory(Intent.CATEGORY_OPENABLE);
            i.setType("*/*");
            MainActivity.this.startActivityForResult(Intent.createChooser(i, "File Browser"), FILECHOOSER_RESULTCODE);
        }

        // For Android 5.0+會呼叫此方法
        @Override
        public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
            Log.d(TAG, "onShowFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture)");
            mUploadCallbackAboveL = filePathCallback;
            Intent i = new Intent(Intent.ACTION_GET_CONTENT);
            i.addCategory(Intent.CATEGORY_OPENABLE);
            i.setType("*/*");
            MainActivity.this.startActivityForResult(
                    Intent.createChooser(i, "File Browser"),
                    FILECHOOSER_RESULTCODE);
            return true;
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        // 處理返回鍵,在webview介面,按下返回鍵,不退出程式
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if (mBridgeWebview != null && mBridgeWebview.canGoBack()) {
                mBridgeWebview.goBack();
                return true;
            }else {
                System.exit(0);
            }
        }
        return super.onKeyDown(keyCode, event);
    }
}

自定義MyHandlerCallBack類

package com.liuw.jsbridge;

import android.text.TextUtils;
import android.util.Log;

import com.github.lzyzsd.jsbridge.BridgeHandler;
import com.github.lzyzsd.jsbridge.CallBackFunction;

/**
 * Created by liuw on 2018/3/6.
 * 自定義Handler回撥
 */

class MyHandlerCallBack implements BridgeHandler {
    private OnSendDataListener mSendDataListener;

    public MyHandlerCallBack(OnSendDataListener mSendDataListener){
        this.mSendDataListener = mSendDataListener;
    }

    @Override
    public void handler(String data, CallBackFunction function) {
        Log.e("liuw","接收資料為:" + data);
        if (!TextUtils.isEmpty(data) && mSendDataListener != null) {
            mSendDataListener.sendData(data);
        }
        function.onCallBack("Native已收到訊息!");
    }

    public interface OnSendDataListener {
        void sendData(String data);
    }
}

自定義MyWebViewClient類

package com.liuw.jsbridge;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.util.Log;
import android.webkit.WebView;

import com.github.lzyzsd.jsbridge.BridgeWebView;
import com.github.lzyzsd.jsbridge.BridgeWebViewClient;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;

/**
 * Created by liuw on 2018/3/6.
 * 自定義WebViewClient
 */

class MyWebViewClient extends BridgeWebViewClient {
    private Context mContext;
    public MyWebViewClient(BridgeWebView mBridgeWebview, Context context) {
        super(mBridgeWebview);
        mContext = context;
    }

    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        Log.i("liuw", "url地址為:" + url);
        try {
            url = URLDecoder.decode(url, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        //預設操作url地址yy://__QUEUE_MESSAGE__/
        if (url.trim().startsWith("yy:")) {
            return super.shouldOverrideUrlLoading(view, url);
        }
        //特殊情況tel,呼叫系統的撥號軟體撥號【<a href="tel:110">撥打電話110</a>】
        if(url.trim().startsWith("tel")){
            Intent i = new Intent(Intent.ACTION_VIEW);
            i.setData(Uri.parse(url));
            mContext.startActivity(i);
        }else {
            //特殊情況【呼叫系統瀏覽器開啟】<a href="https://www.csdn.net">呼叫系統瀏覽器</a>
            if(url.contains("csdn")){
                Intent i = new Intent(Intent.ACTION_VIEW);
                i.setData(Uri.parse(url));
                mContext.startActivity(i);
            } else {//其它非特殊情況全部放行
                view.loadUrl(url);
            }
        }
        return true;
    }
}

建立web.html並放入assets資原始檔夾下,同時將WebViewJavascriptBridge.js也拷入

<html>
<head>
    <meta content="text/html; charset=utf-8" http-equiv="content-type">
    <title>
        js呼叫java
    </title>
</head>

<body>
<p>
    <xmp id="show">Native將要回傳回來的資料展示</xmp>
</p>

<p>
    <input type="text" id="uname" value="使用者名稱"/>
</p>

<p>
    <input type="text" id="psw" value="密碼"/>
</p>

<p>
    <input type="button" id="send" value="發訊息給Native" onclick="sendClick();"
    />
</p>

<p>
    <input type="button" id="use" value="呼叫Native方法" onclick="useClick();"
    />
</p>

<p>
    <input type="file" id="open" value="開啟檔案" onclick="onOpen();"/>
</p>

<p>
    <a href="tel:110">撥打電話110</a>
</p>

<p>
    <a href="http://www.baidu.com">webview瀏覽器</a>
</p>

<p>
    <a href="https://www.csdn.net">呼叫系統瀏覽器</a>
</p>
</body>

<script>

    //Native方法直接呼叫,示例程式碼:mBridgeWebview.loadUrl("javascript:nativeFunction('" + data + "')");
    function nativeFunction(data) {
        document.getElementById("show").innerHTML = data;
    }

    //h5直接通過send向Native傳送訊息,在MyHandlerCallBack的Handler裡接收,並可通過onCallBack方法回傳
    function sendClick() {
        var name = document.getElementById("uname").value;
        var pwd = document.getElementById("psw").value;
        var data = "name = " + name + ", password = " + pwd;

        window.WebViewJavascriptBridge.send(
            data,
            function(responseData) {
                document.getElementById("show").innerHTML = responseData
            }
        );
    }

    //h5通過和Native統一命名方法名,如submitFromWeb來調取java程式碼,如mBridgeWebview.registerHandler("submitFromWeb", new BridgeHandler() {...});
    function useClick() {
            var name = document.getElementById("uname").value;
            var pwd = document.getElementById("psw").value;
            var data = "name = " + name + ", password = " + pwd;

            window.WebViewJavascriptBridge.callHandler(
                'submitFromWeb', {'info':data},
                function(responseData) {
                    document.getElementById("show").innerHTML = responseData;
                }
            );
     }

    function onOpen() {
            var data = "呼叫檔案";
            //call native method
            window.WebViewJavascriptBridge.callHandler(
                'functionOpen'
                , {'param': data }
                , function(responseData) {
                    document.getElementById("open").innerHTML = responseData;
                }
            );
    }

/****************************************************************/
    function connectWebViewJavascriptBridge(callback) {
            if (window.WebViewJavascriptBridge) {
                callback(WebViewJavascriptBridge)
            } else {
                document.addEventListener(
                    'WebViewJavascriptBridgeReady'
                    , function() {
                        callback(WebViewJavascriptBridge)
                    },
                    false
                );
            }
        }

    // 第一連線時初始化bridage
    connectWebViewJavascriptBridge(function(bridge) {
            //也註冊預設的Handler,用來接收java呼叫的send(string,CallBackFunction)方法
            bridge.init(function(message, responseCallback) {
                console.log('JS got a message', message);
                var data = {
                    'Javascript Responds': '測試中文!'
                };
                console.log('JS responding with', data);
                responseCallback(data);
            });
            //註冊handler等待java程式碼呼叫
            //初始化時獲取資料是呼叫此處程式碼
            //引數:標識,要傳遞到JAVA的資料,回撥方法。
            //JAVA程式碼響應的方法:mBridgeWebview.callHandler("functionInJs", new Gson().toJson(實體類物件), new CallBackFunction(){onCallBack(String data)}
            bridge.registerHandler("functionInJs", function(data, responseCallback) {
                document.getElementById("show").innerHTML = ("data from Java: = " + data);
                var responseData = "I am javascript, Data reception success!";
                responseCallback(responseData);
            });
    })
/****************************************************************/
</script>
</html>
最後不要忘了加網路許可權哦
<uses-permission android:name="android.permission.INTERNET"/>

四、總結

1、如果使用registerHandler,那麼native和js中定義的標識必須一致

2、大家如果有出現上傳檔案圖片失敗,可能是適配原因,安卓系統5.0以上需要在WebChromeClient中實現onShowFileChooser()方法,詳情請看程式碼示例

以上總結不完全,程式碼中如有錯誤歡迎指正。

完整程式碼已上傳至GitHub:jsbridge地址