项目中为了减少端上开发量,通常会使用一些跨平台的解决方案,而 web 就是最简单、兼容性最强的方案,但 web 又受制于浏览器,不能直接访问系统的一些属性,而且我们也需要 web 调用 native 的一些方法,所以我们需要一套 web 和 native 双向交互的方案。
目前,Android 要实现与 web 交互有以下几种常用方案:
WebView addJavascriptInterface方法
拦截自定义协议链接实现数据交换
实现 prompt,console等原生方法来数据交互
方案一是官方推荐实现方案,但是在 android 4.2以下存在严重安全漏洞,而且和 JS 交换的数据仅仅局限于基本类型(int,float,double,String 等),不支持直接 JS 函数调用和回调(需要通过注入 JS 支持), 案例:wendux/DSBridge-Android
方案二是兼容 iOS 的方案, 一般情况下前端需要依赖 JS 文件 或者 端上注入 JS, 调用方法固定,方法参数一般为: 函数名, 传递参数和回调函数, 传输数据长度就是 url 长度限制, 不支持同步回调,案例:lzyzsd / JsBridge 和
marcuswestin / WebViewJavascriptBridge
方案三是通过实现 Android WebView 原生方法来交互数据, 执行效率高,不限传输数据, 支持同步和异步传输,但也有弊端, 占据了系统函数,意味着前端使用这个函数就没效果了。
我们今天要介绍的库就是基于第三种方案的改进,基于 prompt 方法来实现 Android 与 Javascript 双向交互。
开源地址:https://github.com/pengwei1024/JsBridge
为什么说它功能强大呢?它可以实现你要想的任意 JS 方法,支持 JS 函数,对象,数组等所有基础类型的解析和回调。我们先来看个示例吧。
如果要实现一个分享功能要怎么做呢?
public class ServiceModule extends JsModule {
@Override
public String getModuleName() {
return "service";
}
@JSBridgeMethod
public void share(String msg, final JBCallback success, final JBCallback failure) {
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, msg);
if (intent.resolveActivity(getContext().getPackageManager()) != null) {
getContext().startActivity(Intent.createChooser(intent, "share"));
success.apply("success");
} else {
failure.apply("failure");
}
}
JS 怎么调用呢?
JsBridge.service.share('分享内容',
function(){
console.log('分享成功')
},
function(){
console.log('分享失败')
}
)