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,
,为了区别我们调用的函数,最终调用Android的方法windrow.android[name](arg)
Android 这边需要的操作
JSONObject jsonObject=new JSONObject(json);String dara=jsonObject.getString("success");//PAG_NATIVE.execCallBackjsPost("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 + ")");
更多相关文章
- Android 驱动之旅 第四章:在Android 系统中编写JNI 方法在应用程
- 一种绕过Android P对非SDK接口限制的简单方法
- Android获取SD卡路径/内存的几种方法
- 【Android增量升级系列_02】 浅谈Android增量更新服务端的实现方
- WebView之js调用Android类的方法传递数据 - 依凡王子
- Android屏幕手势检测的实现代码
- 【Android 内存优化】Bitmap 硬盘缓存 ( Google 官方 Bitmap 示
- Android一套代码适配不同Android版本终极指南
- Unity调用Android原生Java代码以及Unity打开Android原生Activity