如今, 混合开发似乎成为了主流. H5 拥有跨平台的优势, 却存在性能上的问题正好可以用搭建原生壳承载 H5 代码的方式去解决.
如何理解这种方式, 就好像说 Android 原生代码封装外壳, 内部包含 H5 代码作为核心内容. 更细节一点, 我们把引导页, 登录页, 首页等等与业务关联打不并且与用户交互较多的页面用原生去写, 而业务页面, 逻辑代码由 H5 处理, 将他们结合就形成了混合开发的由原生壳承载的 H5APP.
这么做有什么好处呢? 组个例子, 我们利用这种方式做好了一个 Android 原生 APP, 现在需要做一个 IOS 原生 APP, 我们可以直接简单搭建一个 IOS 壳, 复用 H5 代码, 完成 IOS 原生 APP. 同时我们需要在钉钉, 微信小程序等等平台搭建, 可以直接复用我们已有的 H5 代码.
而这样的搭建方式比纯 H5 搭建的 APP 的优势在于因为有原生壳的存在, 可以自由的使用原生 API. 保证了交互上的流畅性.
如何实现原生与 H5 的通信呢?
关于通讯我们需要解决两个问题:
原生向 H5 通讯
H5 向原生通讯
第一个问题很好解决, 以 Android 为例, webView 提供特有的方法, 当你打开一个 html, 你可以去调用这个 Html 中包含的 JS. 例如:
webview.loadUrl("javascript:callH5('Android ok')");
第二个问题我们采用发送指令的方式来处理. 同样以 Android 为例, WebView 可以拦截 html 跳转时的 url 地址, 我们可以利用这个地址, 约定一个规则, 如果符合规则, 则拦截后不执行跳转, 通过这个 url 获取我们需要的信息, 执行对应的操作.
window.location.href=protocol://android?code=toast&data=+Json.stringify(config)
上述是一段 JS 的页面跳转方法. 我们规定规则 PRE=protocol://android?, 当我们拦截的 url 包含 PRE 时, 则我们认为这是一条指令, 不需要跳转页面, 应该执行对应操作. 而参数 code 则是我们的指令内容, data 为通信时的传参.
接下来是原生这边处理. 首先我们拦截 url. 这里笔者还处理由于 Http 攻击导致 H5 页面出现广告的问题. 我们主要是第一个 if.
- webView.setWebViewClient(new WebViewClient() {
- // Load opened URL in the application instead of standard browser
- // application
- public boolean shouldOverrideUrlLoading(WebView view, String url) {
- showLogInfo("拦截到的 url----"+url);
- String advertising="http://"+sharedPreferencesUtil.getData(Constant.IP, RequestConfig.IP)
- +":"+sharedPreferencesUtil.getData(Constant.PORT,RequestConfig.IPPORT);
- if (url.contains(pre)) {
- Map map = getParamsMap(url, pre);
- String code = map.get("code");
- String data = map.get("data");
- parseCode(code, data);
- return true;
- }else if(!url.contains(advertising)){
- showLogError("拦截到植入广告, 广告的 url--"+url);
- return true;
- } else{
- return false;
- }
- }
- });
return 为 ture 表示拦截成功, 不执行后面的跳转操作. 而 false 表示按正常流程执行. 拦截成功后我们从 url 中获取 code 和 data, 接着就可以按照我们自己的需求去处理了.
来源: http://mobile.51cto.com/ahot-580204.htm