android 混编JsBridge的原理和实现
来源:互联网 发布:农村淘宝可以贷款 编辑:程序博客网 时间:2024/05/18 02:50
首先我们先要知道
js调用Android的方法有以下四种:
- WebView的JavascriptInterface
- WebViewClient.shouldOverrideUrlLoading()
- WebChromeClient.onConsoleMessage()
- WebChromeClient.onJsPrompt()
1. JavascriptInterface
JavascriptInterface是Android官方提供的工js和Native通信方案。其实现如下:
- 实现一个java类,供js调用
public class JavascriptInterface {@JavascriptInterface public void showToast(String toast) { Toast.makeText(MainActivity.this, toast, Toast.LENGTH_SHORT).show(); }}
- 在webView中注册这个类:
webView.addJavascriptInterface(new JavascriptInterface(), "javascriptInterface");
- 在js中直接调用这个接口:
function showToast(text){ window.javascriptInterface.showToast(text);}
但是webView有个安全漏洞:WebView中接口隐患与手机挂马利用。 在Android4.2后,这个漏洞被修复;但是考虑到兼容性的问题,这个方案基本不被采用。
2. WebViewClient.shouldOverrideUrlLoading()
这个方法是拦截所有webView的跳转,页面可以构造一个特殊格式的Url跳转,shouldOverrideUrlLoading拦截Url后判断其格式,然后Native就能执行自身的逻辑了。
public class CustomWebViewClient extends WebViewClient {@Override public boolean shouldOverrideUrlLoading(WebView view, String url) { if (isJsBridgeUrl(url)) { // JSbridge的处理逻辑 return true; } return super.shouldOverrideUrlLoading(view, url); } }
3. WebChromeClient.onConsoleMessage()
在js中执行console.log(), 会进入Android的WebChromeClient.consoleMessage()回调。
public class CustomWebChromeClient extends WebChromeClient {@Override public boolean onConsoleMessage(ConsoleMessage consoleMessage) { super.onConsoleMessage(consoleMessage); String msg = consoleMessage.message();//Javascript输入的Log内容 } }
4. WebChromeClient.onJsPrompt()
和3类似,在js中执行alert、confirm和prompt这三个方法时,会进入Android的onJsAlert、onJsConfirm和onJsPrompt回调。 由于prompt的使用频率较低,因此通常采用prompt实现js和Native的通信。
Android调用js
Android调用js接口的方法只有一个:WebView.loadUrl():
webView.loadUrl('javascript: ' + ...);
Android中的JSBridge是H5与Native通信的桥梁,至于demo在http://blog.csdn.net/roshen_android/article/details/73825781已经详细说明了,大家可以下载demo去看看先来看看registerHandler
/** * register handler,so that javascript can call it * * @param handlerName * @param handler */public void registerHandler(String handlerName, BridgeHandler handler) { if (handler != null) { messageHandlers.put(handlerName, handler); }}
可以看到其内部是将js调用native的请求添加到一个
Map<String, BridgeHandler> messageHandlers = new HashMap<String, BridgeHandler>();
中去,然后你会发现messageHandlers最终还是去到
BridgeHandler handler;if (!TextUtils.isEmpty(m.getHandlerName())) { handler = messageHandlers.get(m.getHandlerName());} else { handler = defaultHandler;}if (handler != null){ handler.handler(m.getData(), responseFunction);}
这就是js调用Native回调回来的,至于这个回调可以看到
public BridgeWebViewClient(BridgeWebView webView) { this.webView = webView;}@Overridepublic boolean shouldOverrideUrlLoading(WebView view, String url) { try { url = URLDecoder.decode(url, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } if (url.startsWith(BridgeUtil.YY_RETURN_DATA)) { // 如果是返回数据 webView.handlerReturnData(url); return true; } else if (url.startsWith(BridgeUtil.YY_OVERRIDE_SCHEMA)) { // webView.flushMessageQueue(); return true; } else { return super.shouldOverrideUrlLoading(view, url); }}
,下面来看看Native调用js,该调用主要是callHandler
/** * call javascript registered handler * * @param handlerName * @param data * @param callBack */public void callHandler(String handlerName, String data, CallBackFunction callBack) { doSend(handlerName, data, callBack);}一步一步点下去你会发现最终去到
void dispatchMessage(Message m) { String messageJson = m.toJson(); //escape special characters for json string messageJson = messageJson.replaceAll("(\\\\)([^utrn])", "\\\\\\\\$1$2"); messageJson = messageJson.replaceAll("(?<=[^\\\\])(\")", "\\\\\""); String javascriptCommand = String.format(BridgeUtil.JS_HANDLE_MESSAGE_FROM_JAVA, messageJson); if (Thread.currentThread() == Looper.getMainLooper().getThread()) { this.loadUrl(javascriptCommand); } }
看到红色的字体没,就是Native唯一调用js的方法。
-----------------------------------------------------------------------------------------------------------------------------------------------
总结了下,JsBridger无非都是为我们搭建了更好的桥梁,让我们更好的优化hybrid的架构。
阅读全文
0 0
- android 混编JsBridge的原理和实现
- Android JSBridge的原理与实现 (prompt和javascript)
- Android JSBridge的原理与实现 (prompt和javascript)
- Android JSBridge的原理与实现
- Android JSBridge的原理与实现
- Android JSBridge的原理与实现
- Android JSBridge的原理与实现
- Android JSBridge的原理与实现
- Android JSBridge的原理与实现
- Android JSBridge的原理与实现
- JsBridge实现JavaScript和Android的互相调用
- JsBridge实现及原理
- Android JSBridge实现与前端的交互
- [HyBrid]HyBrid混编初尝:原生和第三方JsBridge的使用
- Android,IOS中JSBridge原理
- 【转】JsBridge实现JavaScript和Java的互相调用
- Android WebView 实现JS相互调用 JsBridge
- 使用jsBridge和原生IOS、Android交互
- 《TP5.0学习笔记---对Mysql数据库的操作(一)》
- H264码率设置
- 【SC17观察】“Inspur is our answer”背后 浪潮诠释国际化提速新模式
- s'd's
- Linux负载均衡软件——LVS
- android 混编JsBridge的原理和实现
- Unity导入模型贴图一面透明
- vim 安装与配置
- 【SC17观察】美国丹佛现场直击SC17 探寻计算力增长的困局和破局
- 访问权限修饰符范围详解
- Chrome浏览器 json格式乱码
- 有限元分析时是网格画的越细越精确吗?
- 即时通讯中语音视频聊天后面的技术支持有哪些
- 关于虚拟机下centOS版linux系统ifconfig只显示inet6ip,不显示inet4ip的问题