Android webview注入自己的js代码(js传入function等其他参数解决)

问题产生原因:

前端与Android 交互时,调用Android 的方法,但是传入的参数是function

例如:

Android webview注入自己的js代码(js传入function等其他参数解决)_第1张图片

这样我们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是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 + ")");

 

你可能感兴趣的:(问题一览)