Android webview注入自己的js代碼(js傳入function等其他參數解決)

問題產生原因:

前端與Android 交互時,調用Android 的方法,但是傳入的參數是function

例如:

這樣我們Android這邊接收不到值(我網上百度是沒找到好方法,有的說讓前端傳入jsonString給我們,能解決方法,但是前端要改動代碼)

解決思路:

我們加入一箇中間層,當js調用Android時,先調其他方法,使傳入值變成json在調用Android方法,這樣就可以接收了

實現方案:

注入js代碼,js不會寫,從別人借鑑過來的

jsString = "(function() {\n" +
        "    var PAG_NATIVE = window.PAG_NATIVE = {};\n" +
        "    PAG_NATIVE.callbacks = {};\n" +
        "    PAG_NATIVE.callBacks = {};\n" +
        "    PAG_NATIVE.exec = function(funName, args, callbackId) {\n" +
        "        var commend = {\n" +
        "            functionName: funName,\n" +
        "            arguments: args,\n" +
        "            callbackId: callbackId\n" +
        "        };\n" +
        "        window.android[funName](args);\n" + "    };\n" +
        "    PAG_NATIVE.execCallBack = function(callbackId, res) {\n" +
        "        var callBack = PAG_NATIVE.callBacks[callbackId];\n" +
        "        if (callBack) {\n" +
        "            callBack(res);\n" +
        "            delete PAG_NATIVE.callBacks['callbackId'];\n" +
        "        }\n" +
        "    };\n" +
        "    PAG_NATIVE.openBluetoothAdapter = function(object) {\n" +
        "        var result = PAG_NATIVE.transformObject(object);\n" +
        "        PAG_NATIVE.exec('openBluetoothAdapter', result, \"\");\n" +
        "    };\n" +
        "\n" +
        "    PAG_NATIVE.transformObject = function(object) {\n" +
        "        for (key in object) {\n" +
        "            if (typeof (object[key]) == 'function') {\n" +
        "                var identifier = (new Date()).getTime() + key;\n" +
        "                PAG_NATIVE.callbacks[identifier] = object[key];\n" +
        "                object[key] = identifier;\n" +
        "            }\n" +
        "        }\n" +
        "        return JSON.stringify(object);\n" +
        "    };\n" +
        "\n" +
        "    PAG_NATIVE.commonCallback = function(object) {\n" +
        "        for (key in object) {\n" +
        "            if (typeof (PAG_NATIVE.callbacks[key]) == 'function') {\n" +
        "                PAG_NATIVE.callbacks[key](object[key]);\n" +
        "                PAG_NATIVE.callbacks['key'] = null;\n" +
        "            }\n" +
        "        }\n" +
        "};\n" +
        "})();";

注入調用

webview.loadUrl("javascript:"+NativeCommonJS.addJS());

時機是在webview onpagerFinish中調用,可以延遲1s加載,保證,網頁加載完畢

說明一下:利用集合記錄每一個的function,<k,v>,k是function加時間戳 ,v是原方法function,至於給方法加時間戳,是因爲,很多方法體可能同名:多個success。然後加入每調用增加一個方法,就要類似PAG_NATIVE.openBluetoothAdapter一樣,新增一個方法名,這個方法名是給前端js調用的,經過transformObject,將傳入值轉成了json,

,爲了區別我們調用的函數,最終調用Android的方法windrow.android[name](arg)

 

Android 這邊需要的操作

JSONObject jsonObject=new JSONObject(json);
String dara=jsonObject.getString("success");
//PAG_NATIVE.execCallBack
jsPost("PAG_NATIVE.commonCallback", "{'"+dara+"':12345" +"}");
//調用js方法
public void jsPost(final String method, final Object data) {
    handler.post(new Runnable() {
        @Override
        public void run() {
            webView.loadUrl("javascript:"+method+"(" + data + ")");
        }
    });
}

我用handle的原因是,子線程不能調用loadurl,可自行刪除

注意點:參數的拼接

"{'"+dara+"':12345" +"}"

1234可以直接放我們定義的對象,不需要tostring,js調用直接res.參數名

這是我目前的解決方法,感覺並不智能,也很繁瑣,只能解決特定的事,希望有好的思路可以留言

-------------------------------------

追記,上面實現了傳object,傳多個方法名的,但是一種特殊的,傳一個匿名方法funtcion,這個需要額外處理

前端js代碼

這個比傳object簡單,我們只要記住function名字就行了

js調Android中間轉換

"    PAG_NATIVE.onBLECharacteristicValueChange = function(callback) {\n" +
"            PAG_NATIVE.callBacks['onBLECharacteristicValueChange'] = callback;\n" +
"            PAG_NATIVE.exec('onBLECharacteristicValueChange','{\"function\":\"onBLECharacteristicValueChange\"}', \"\");"+
"    };"

android調js中間轉換

"    PAG_NATIVE.execCallBack = function(callbackId, res) {\n" +
"        var callBack = PAG_NATIVE.callBacks[callbackId];\n" +
"        if (callBack) {\n" +
"            callBack(res);\n" +
"            delete PAG_NATIVE.callBacks['callbackId'];\n" +
"        }\n" +
"    };\n" +

 java代碼

webView.loadUrl("javascript:" + testMethod2 + "('" + callback + "'," + data + ")");

 

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