专栏首页Flutter从0到1构建大前端应用Hybrid前端jsbridge设计原理分析

Hybrid前端jsbridge设计原理分析

时下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

        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一个方法:

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

参数传递

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

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

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

方法回调

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

        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端执行回调写法:

    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封装完毕后,可以测试,以分享为例:

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

基于vue的封装

只需载入brige.js即可

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端。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Flutter之Android层面源码分析(一)

    学习Flutter过程中,先撸了一遍Flutter,写了个仿boss直聘的demo, github地址:flutter_boss. 写完之后其实比较迷茫,and...

    kimihe
  • Flutter实现一个酷炫带动画的列表型多选日历组件

    由于项目需要,用Flutter重构了之前用Android做过的日历组件,整体效果感觉不错,流畅度甚至超过原来的,这里需要提一下官网的做法,如下:

    kimihe
  • Flutter:使用手势识别做一个360旋转展物

    最近在复习Flutter的GestureDetector相关知识时,想到了以前用Android实现的展物项目,这次完整的用Flutter实现了一下,真是感觉代码...

    kimihe
  • Web技术与Native APP进入融合时代

    如果说以前的微信公众号还是一个媒体化的平台,那么2016年的公众号会有一种新的形态,叫应用号。应用号预示着比公众号更强大的功能、更优质的体验以及更丰富的服务。应...

    非著名程序员
  • webpack下css/js/html引用图片的正确方式

    在webpack的处理下,为了使引用的图片被打包编译(以把src的图片文件编译到dist中或者对src的文件进行base64编码),应使用如下引用方式:

    smy
  • 斐波那契

    用户6783014
  • Hystrix工作流程解析

    首先我们看一下上方的这张图,这个图完整的描述了Hystrix的工作流程:1.每次调用都会创建一个HystrixCommand 2.执行execute或queue...

    Java学习录
  • 5.5 VR扫描:Valve Index头显开放预购;谷歌与《大侦探皮卡丘》合作推出AR表情包

    近日,在美国圣何塞麦克内里会议中心召开的Facebook F8年度开发者大会上,扎克伯格正式宣布两款新硬件的发售——VR一体机Oculus Quest和PC V...

    VRPinea
  • 对基本类型包装类常量池的补充

    作为Integer类的内部类。这段注释非常关键。意思是说,IntegerCache对-128-127之间的数据自动装箱支持。在IntegerCache第一次使用...

    冬天里的懒猫
  • mtr使用详解

    当客户端访问目标服务器或负载均衡,使用ping命令测试出现丢包或不通时,可以通过MTR等工具进行链路测试来判断问题来源。

    阿dai学长

扫码关注云+社区

领取腾讯云代金券