在字节跳动实习了一段时间,JSBridge使用的比较频繁,之前只是看了些简单的JSBridge概念,一直没有时间去了解从客户端到JavaScript的一个通信原理(JSBridge)。最近花了点时间学习了从Android端到JavaScript的通信-JSBridge(主要是太闲了),对JSBridge有了更深入的理解,特地写下了这篇文章分享一下。
JSBridge是什么
顾名思义:就是JavaScript(H5)与Native通信的桥梁,在H5开发中经常有操作客户端的需求,比如获取App信息,打开/关闭一个WebView,吊起支付面板等等,但这些功能只能在Native中实现,因此诞生JSBridge,通过JSBridge与Native通信,赋予了JavaScript操作Native的能力,同时也给了Native调用JavaScript的能力。
JSBridge与Native间通信原理
在H5中JavaScript调用Native的方式主要用两种
- 注入API,注入Native对象或方法到JavaScript的window对象中(可以类比于RPC调用)。
- 拦截URL Schema,客户端拦截WebView的请求并做相应的操作(可以类比于JSONP)。
下面将以Android端的JSBridge通信为例,讲解这两种方式的实现原理(本人比较菜,只会Java不会Swift和OC😭)。
注入API
通过WebView提供的接口,向JavaScript的window中注入对象或方法(Android使用addJavascriptInterface()
方法),让JavaScript调用时相当于执行相应的Native逻辑,达到JavaScript调用Native的效果。
对于Android实现方式如下,核心代码在于
webView.addJavascriptInterface(new InjectNativeObject(this), "NativeBridge");
示例如下
在Android的main页面放一个Webview
然后Android端对应的代码如下
public class MainActivity extends AppCompatActivity {
private WebView webView;
// 不要用localhost或127.0.0.1
private final String host = "192.168.199.231";
public class InjectNativeObject {
// 注入到JavaScript的对象
private Context context;
public InjectNativeObject(Context context) {
this.context = context;
}
@JavascriptInterface
public void openNewPage(String msg) {
// 打开新页面,接受前端传来的参数
if (msg.equals("")) {
Toast.makeText(context, "please type!", Toast.LENGTH_LONG).show();
return;
}
startActivity(new Intent(context, SecondActivity.class));
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
}
@JavascriptInterface // 存在兼容性问题
public void quit() {
// 退出app
finish();
}
}
@SuppressLint("SetJavaScriptEnabled")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = findViewById(R.id.loginWebView);
webView.getSettings().setJavaScriptEnabled(true);
// JS注入
webView.addJavascriptInterface(new InjectNativeObject(this), "NativeBridge");
webView.loadUrl(String.