JsBridge
简介
Android JsBridge 就是用来在 Android app的原生 java 代码与 javascript 代码中架设通信(调用)桥梁的辅助工具。
有问题请联系 xesam
原理概述
Javascript 运行在 WebView 中,而 WebView 只是 Javascript 执行引擎与页面渲染引擎的一个包装而已。
由于这种天然的隔离效应,我们可以将这种情况与 IPC 进行类比,将 Java 与 Javascript 的每次互调都看做一次 IPC 调用。
如此一来,我们可以模仿各种已有的 IPC 方式来进行设计,比如 RPC。本文模仿 Android 的 Binder 机制来实现一个 JsBridge。
首先回顾一一下基于 Binder 的经典 RPC 调用:
当然,client 与 server 只是用来区分通信双方责任的叫法而已,并不是一成不变的。
对于 java 与 javascript 互调的情况,当 java 主动调用 javascript 的时候,java 充当 client 角色,javascript 则扮演 server 的角色,
javascript 中的函数执行完毕后回调 java 方法,这个时候,javascript 充当 client 角色,而 javascript 则承担 server 的责任。
剩下的问题就是怎么来实现这个机制了,大致有这么几个需要解决的问题:
- java 如何调用 Javascript
- Javascript 如何调用 java
- 方法参数以及回调如何处理
- 通信的数据格式是怎样的
下面逐个讨论这些问题:
1. java 如何调用 Javascript
要实现 Java 与 Javascript 的相互调用,有两条途径可以考虑:
- 集成一个定制化的 Javascript 与 Html 渲染引擎,java 通过引擎底层与 Javascript 交互。这样可以获得完全的控制权。
- 使用 Android Sdk 提供的交互方法。
对于第一种途径,代价比较大,而且技术方案比较复杂,一般只有基于 Javascript 的跨平台开发方案才会这么做。
所以,现在着重考查第二种途径。
Android 的默认 Sdk 中, Java 与 Javascript 的一切交互都是依托于 WebView 的,大致有以下几个可用方法:
第一:
webView.loadUrl("javascript:scriptString"); //其中 scriptString 为 Javascript 代码
第二,在 KITKAT 之后,又新增了一个方法:
webView.evaluateJavascript(scriptString, new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
}
});//其中 scriptString 为 Javascript 代码,ValueCallback 的用来获取 Javascript 的执行结果。这是一个异步掉用。
这个调用看起比上面的正常,而且更像是一个方法调用。
需要注意的是,ValueCallback 并不是在 UI 线程里面执行的。
2. Javascript 如何调用 java
要实现 Javascript 调用 java 方法,需要先在 Javascript 环境中注入一个 Java 代理:
class JavaProxy{
@JavascriptInterface //注意这里的注解。出于安全的考虑,4.2 之后强制要求,不然无法从 Javascript 中发起调用
public void javaFn(){
//xxxxxx
};
}
webView.addJavascriptInterface(new JavaProxy();, "java_proxy");
然后在 Javascript 环境中直接调用 obj_proxy 代理上的方法即可。