JSBridge初探
为何关注JSBridge
自从2017年1月9日,微信小程序上线后,小程序生态已经吸引了大批的开发者入驻,开发快捷,快速部署,跨平台是小程序几个优点。到如今各个大平台都会根据自身业务实现各自的小程序平台。小程序隐隐成为新的流量入口。应用生态慢慢再向泛应用生态转变。在这个泛应用生态上会不会有安全问题,我们的检测如何触达;另外小程序框架有没有可能在我们未来的SDK或者2C应用中进行使用?带着这些问题去研究了小程序框架中最重要的核心功能JSBridge。在看技术之前还是回顾一下小程序的历史和现在的状况。
小程序平台发展时间线
2017年1月 微信小程序上线
2018年3月 快应用发布
2018年7月 百度智能小程序上线
2018年9月 支付宝程序、淘宝轻店铺上线
2018年10月 抖音小程序上线
2018年11月 头条小程序上线
2019年5月 QQ小程序上线
2019年7月 360小程序上线
2019年10月 美团小程序上线
小程序数量

据艾媒网统计,2020年小程序数量将达到1400w+
JSBridge是什么
JSBridge很早就出现在软件开发中,它提供一个JS和Native互相调用的功能。在移动开发中,Natvie层指的就是APP的Java层,使用了JSBridge的H5页面可以通过js调用原生系统的一些功能,如打开通讯录,打开相册选取照片等等功能。 微信早期为自己的应用已经提供基于JSBridge的功能,叫WeiXinJSBridge,后来发现这套机制可以抽象统一后对外提供,于是现在微信的JSBridge被封装成JSSDK,也就有了后来的小程序的兴起。

JSBridge的基本框架如上图所示 在Android中使用的是Google的Webkit框架,其中Webview是支持将Native方法注册到一个js函数上,用来处理js层的调用 同样Webview也有一个evaluateJavascript方法可以调用已经加载的js方法 JSBridge其实就是利用上述两个方法进行封装而成的JS和JAVA层相互通信的通道。
JSBridge的小例子
俗话说的好Talk is cheap. Show me the code
。为了更深刻的理解js和native的交互过程,写了一个最简单的例子。
首先创建一个app工程,就用
empty view
就可以修改layout的activity_main.xml, 创建Webview
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <WebView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/webView" /> </androidx.constraintlayout.widget.ConstraintLayout>
在src/main路径下创建assets目录,并在assets目录下创建index.html文件,写入如下内容
<!DOCTYPE html> <html> <head> <title>WebView与JS方法交互</title> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="this is my page"> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <!--<link rel="stylesheet" type="text/css" href="./styles.css">--> </head> <body> <input type="button" value="Say hello" onClick="showAndroidToast('Hello Android!')" /> <script type="text/javascript"> //调起本地的Java方法 function showAndroidToast(toast) { window.Android.showToast(toast); } </script> </body> </html>
修改MainActivity
package com.wq.jsbridge; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.webkit.JavascriptInterface; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.Toast; public class MainActivity extends AppCompatActivity { private WebView mWebView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initWebView(); } private void initWebView() { WebView mWebView = (WebView) findViewById(R.id.webView); //启用支持javascript WebSettings settings = mWebView.getSettings(); settings.setJavaScriptEnabled(true); mWebView.addJavascriptInterface(new JsBridgeJavaScriptInterface(), "Android"); //WebView加载web资源 mWebView.loadUrl("file:///android_asset/index.html"); //覆盖WebView默认使用第三方或系统默认浏览器打开网页的行为,使网页用WebView打开 mWebView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { // TODO Auto-generated method stub //返回值是true的时候控制去WebView打开,为false调用系统浏览器或第三方浏览器 view.loadUrl(url); return true; } }); } final class JsBridgeJavaScriptInterface { /** JS调用native方法显示一个Toast */ @JavascriptInterface public void showToast(String toast) { Toast.makeText(getApplicationContext(), toast, Toast.LENGTH_SHORT).show(); } } }
之后编译运行时就可以看到Activity中出现了一个button,点击button就会调用到Native的Toast方法进行
下一步如何丰富这个例子
上面的例子展示了如何从js方法中调用native方法,并没有展示Java回调js的过程,并且也没有对接口进行统一封装 回调的实现可以有两种方式:
返回值通过Native方法的返回值给出,一般是string类型,这个返回值可以直接返回到js方法中,在js中添加对返回值的处理函数
在js层实现一个供native调用的统一入口,在native执行完成后,准备返回值和callback函数名,通过evaluateJavascript方法处理
封装的话主要是对js调用native的接口以及native调用js的接口进行统一约定,其中包含API 名,参数格式,返回值格式等等
参考项目
ZJsBridge 这个项目很好的展示了双向调用的过程,并且整个代码结构也很清晰,可以作为后续使用和优化的参考
Last updated
Was this helpful?