前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Hybrid前端jsbridge设计原理分析

Hybrid前端jsbridge设计原理分析

作者头像
kimihe
发布2020-03-28 19:48:09
1.7K0
发布2020-03-28 19:48:09
举报

时下app分以下几种技术选型

  1. Webapp,框架有cordova,ionic等
  2. Hybrid,即Native+h5方式
  3. React Native, weex方向
  4. 纯Native,这个没啥好说的
  5. flutter,明日之星 本文只描述Hybrid中的jsbrige部分实现原理,不会涉及Native部分的webview如何设计,关于webview的文章太多了,可以参考别的文章

通信原理

预先定义好schema,如myapp://... 通过前端发送伪连接请求iframe.src

代码语言:javascript
复制
        var iframe = document.createElement('iframe')
        iframe.style.display = 'none'
        iframe.src = schema
        var body = document.body
        body.appendChild(iframe)
        setTimeout(function () {
            body.removeChild(iframe)
            iframe = null
        })
复制代码

可以看到,在某个按钮或者行为需要与原生端通信时创建一个iframe然后再移除,如果不移除iframe,则会在body里出现大量无用的iframe标签,这里简单说一下Native怎么去拦截这个伪链接请求。 在WebviewClient里override一个方法:

代码语言:javascript
复制
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        if (url.startsWith(SCHEMA)) {
            ...
            return true;
        }
    }
复制代码

参数传递

实际项目中,肯定是要传递参数给Native接收的,可以对这样封装

代码语言:javascript
复制
        for (key in data) {
            if (data.hasOwnProperty(key)) {
                schema += '&' + key + data[key]
            }
        }
复制代码

这样就可以拼接出&key=value这种形式,Native端可以写一个方法获取到key和value的值然后去做相应的处理。

方法回调

有的时候bridge事件处理完之后需要告诉前端一些消息回馈,那么前端需要封装一个callbackName传给Native端

代码语言:javascript
复制
        var callbackName = ''
        if (typeof callback === 'string') {
            callbackName = callback
        } else {
            callbackName = action + Date.now()
            console.log('callbackName: ' + callbackName)
            window[callbackName] = callback
        }
        schema += 'callback=' + callbackName
复制代码

特别注意:这里有一个Date.now(),作用是为了避免回调方法重复,且避免在ios手机上不断点击造成界面阻塞UI失去响应。

Native端执行回调写法:

代码语言:javascript
复制
    public static void call(WebView webview, String js) {
        if (webview != null) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                webview.evaluateJavascript(js, null);
            } else {
                webview.loadUrl("javacript:" + js);
            }
        }
    }
复制代码

用法举例

jsbrige封装完毕后,可以测试,以分享为例:

代码语言:javascript
复制
      window.bridge.share({
        title: '...',
        content: '...'
      }, function (result) {
        if (result.success) {
          alert('分享成功')
        }
      })
复制代码

基于vue的封装

只需载入brige.js即可

代码语言:javascript
复制
import './bridge'
import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

new Vue({
  render: h => h(App)
}).$mount('#app')
复制代码

总结

  1. 在ios上不要使用UIWebview,使用WkWebview。
  2. android要注意webview内存泄漏问题。
  3. 前端要控制打包体积,不推荐用webpack,因为会生成大量的webpack的封装代码。
  4. 推荐使用rollup轻量级前端工程化打包,不会生成多余的js代码。
  5. 推荐使用多页模式,Native端通过pushwindow等方法,把跳转权交给Native端。
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018年03月23日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 时下app分以下几种技术选型
  • 通信原理
  • 参数传递
  • 方法回调
  • 用法举例
  • 基于vue的封装
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档