Android Native 和 H5 交互
使用 @JavascriptInterface 注解的方式
Android 4.2 版本之前的 WebView.addJavascriptInterface()
接口引起的漏洞,可能导致恶意网页通过 Js 方法遍历刚刚通过 addjavascriptInterface 注入进来的类的所有方法从中获取到 getClass 方法,然后通过反射获取到 Runtime 对象,进而调用 Runtime 对象的 exec 方法执行一些操作。
1 | function execute(cmdArgs) { |
Native 端代码:
1 | webSettings.setJavaScriptEnabled(true); |
- Native 中的方法是供 H5 调用的,不能混淆,不能更改,耦合性高。
- 因为 APP 是宿主,可以直接访问 H5,就是在 H5 中曝露一些全局对象(包括方法),然后在原生 app 中调用这些对象。
H5 代码:
1 | <html> |
优点:
- 官方推荐;
- 实现方便简单;
缺点:
- 4.2(api 17) 以下存在安全隐患;
- 兼容性差;
- 不能混淆,方法名不能更改,耦合性太高;
自定义路由协议
scheme://host:port/path?query
H5 请求消息:
jsbridge://app.demo.com:111/login?params={“channel”:”h5”}
- jsbridge://app.demo.com 为 JsBridge 标识;
- 111 为 H5 请求码,用于区分同一个方法的不同请求。H5 自定义,Native 会原样返回;
- login 为本地方法;
- params 为请求参数,Json 格式。参数可能需要 URL 编码;
Native 响应消息:
1 | { |
- code 为响应码。0 成功;1 失败。
- message 为响应消息。
- function 为 Native 端处理完成后,将消息返回给 H5 的回调方法。
- requestCode 是 H5 请求码。
- data 字段为具体的业务字段,需提前约定好。
大致有如下几个步骤:
- 约定接口,如
jsbridge://app.demo.com:111/login?params={"channel":"h5"}
,H5 调用 window.prompt() 传递给 Native; - Native 在
WebChromeClient#onJsPrompt()
方法中接收到 H5 传递的 Json 字符串; - Native 解析字符串获取到请求方法,参数等,反射获取类(类名,参数要预先定义好)中的方法。方法处理后生成响应 Json 字符串;
- 最后响应字符串通过调用
WebView#evaluateJavascript()
方法参数传递给 H5。
Js 中对应的 window.alert()、window.confirm()、window.prompt()这三个方法的调用在 WebChromeClient 中都有对应的回调方法,分别为:
onJsAlert()、onJsConfirm()、onJsPrompt(),对于它们传入的 message,都可以在相应的回调方法中接收到。所以,对于 Js 调 Native 方法,我们可以借助这个信道,和前端协定好一段特定规则的 message。
跨平台解决框架
React Native
- Facebook 出品;
- JavaScript 语言;
- JSCore 引擎;
- React 设计模式;
- 原生渲染;
React Native 是利用 JS 来调用 Native 端的组件,从而实现相应的功能。
如下图所示,RN 的跨平台实现主要由三层构成,其中 C++ 实现的动态连结库(.so),作为中间适配层桥接,实现了 js 端与原生端的双向通信交互。这里最主要是封装了 JavaScriptCore 执行 js 的解析,而 react native 运行在 JavaScriptCore 中,所以不存在浏览器兼容的问题。
Weex
- Alibaba 出品;
- JavaScript 语言;
- JS V8 引擎;
- Vue 设计模式;
- 原生渲染。
Flutter
- Google 出品;
- Dart 语言;
- Flutter Engine 引擎;
- 响应式设计模式;
- 原生渲染。
与 react native 和 weex 的通过 Javascript 开发不同,Flutter 的编程语言是 Dart,所以执行时并不需要 Javascript 引擎,但实际效果最终也通过原生渲染。
参考
[1] cxzl/JSBridge
[2] lzyzsd/JsBridge
[3] Native 与 H5 交互的那些事
[4] Sunzxyong/JsBridge
[5] pengwei1024/JsBridge
[6] 最火跨平台 React Native+weex+Flutter