一、前言

如今的互联网时代也称移动互联网时代,基本上每个人每天都会花费大量时间在移动设备上,早期的移动端应用大都使用原生开发(android,ios),而现在的移动开发技术选型上基本都是混合开发(Hybrid),混合开发是一种开发模式,指使用多种开发模型开发App,通常会涉及到两大类技术:原生Native、Web H5

原生技术主要指iOS(Objective C)、Android(Java),原生开发效率较低,开发完成需要重新打包整个App,发布依赖用户的更新,性能较高功能覆盖率更高,发布流程较为复杂

Web H5主要由HTML、CSS、JavaScript组成,Web可以更好的实现发布更新,跨平台也更加优秀,但性能较低,功能实现也受限

混合开发的意义就在于吸取两者的优点,而且随着手机硬件的升级迭代、系统(Android 5.0+、ISO 9.0+)对于Web特性的较好支持,H5的劣势被逐渐缩小

原生、Web相互通信都离不开JSBridge

二、JSBridge做了些什么?

Hybrid模式下,H5会经常需要使用Native的功能,比如打开二维码扫描、调用原生页面、获取用户信息等,同时Native也需要向Web端发送推送、更新状态等,而JavaScript是运行在单独的JS Context(Webview容器、JSCore等),与原生有运行环境的隔离,所以需要有一种机制实现Native端和Web端的双向通信,这就是JSBridge以JavaScript引擎或Webview容器作为媒介,通过协定协议进行通信,实现Native端和Web端双向通信的一种机制。

通过JSBridge,Web端可以调用Native端的Java接口,同样Native端也可以通过JSBridge调用Web端的JavaScript接口,实现彼此的相互调用。

三、什么是WebView?

首先了解下webViewwebView是移动端(原生)提供的运行JavaScript的环境,它是一种嵌入式浏览器,原生应用可以用它来展示网络内容。可与页面JavaScript交互,实现混合开发,其中AndroidiOS又有些不同:

AndroidWebView采用的是低版本和高版本使用了不同的webkit内核,4.4后直接使用了Chrome。

iOSUIWebView算是自IOS2就有,但性能较差,特性支持较差,WKWebViewiOS8之后的升级版,性能更强特性支持也较好。

WebView控件除了能加载指定的url外,还可以对URL请求、JavaScript的对话框、加载进度、页面交互进行强大的处理,之后会提到拦截请求、执行JS脚本都依赖于此。

四、JSBridge的实现原理

Web端和Native可以类比于Client/Server模式,Web端调用原生接口时就如同Client向Server端发送一个请求类似,JSBridge在此充当类似于HTTP协议的角色,实现JSBridge主要是两点:

  • 将Native端原生接口封装成JavaScript接口
  • 将Web端JavaScript接口封装成原生接口

4.1 Native->Web

首先来说Native端调用Web端,这个比较简单,JavaScript作为解释性语言,最大的一个特性就是可以随时随地地通过解释器执行一段JS代码,所以可以将拼接的JavaScript代码字符串,传入JS解析器执行就可以,JS解析器在这里就是webView。

4.2 Web->Native

Web调用Native端主要有两种方式

  • 4.2.1 拦截Webview请求的URL Schema

    URL Schema是类URL的一种请求格式,格式如下:
<protocol>://<host>/<path>?<qeury>#fragment

我们可以自定义JSBridge通信的URL Schema,比如:jsbridge://showToast?text=hello

Native加载WebView之后,Web发送的所有请求都会经过WebView组件,所以Native可以重写WebView里的方法,拦截Web发起的请求,我们对请求的格式进行判断:

如果符合我们自定义的URL Schema,对URL进行解析,拿到相关操作、操作,进而调用原生Native的方法

如果不符合我们自定义的URL Schema,我们直接转发,请求真正的服务

Web发送URL请求的方法有这么几种:

a标签
location.href
使用iframe.src
发送ajax请求
这些方法,a标签需要用户操作,location.href可能会引起页面的跳转丢失调用,发送ajax请求Android没有相应的拦截方法,所以使用iframe.src是经常会使用的方案

安卓提供了shouldOverrideUrlLoading方法拦截

IOSUIWebView使用shouldStartLoadWithRequest

IOSWKWebView则使用decidePolicyForNavigationAction

这种方式从早期就存在,兼容性很好,但是由于是基于URL的方式,长度受到限制而且不太直观,数据格式有限制,而且建立请求有时间耗时。

  • 4.2.2 向Webview中注入JS API

    这个方法会通过webView提供的接口,App将Native的相关接口注入到JSContext(window)的对象中,一般来说这个对象内的方法名与Native相关方法名是相同的,Web端就可以直接在全局window下使用这个全局JS对象,进而调用原生端的方法。

Android(4.2+)提供了addJavascriptInterface注入:

// 注入全局JS对象
webView.addJavascriptInterface(new NativeBridge(this), "NativeBridge"); class NativeBridge {
private Context ctx;
NativeBridge(Context ctx) {
this.ctx = ctx;
} // 增加JS调用接口
@JavascriptInterface
public void showNativeDialog(String text) {
new AlertDialog.Builder(ctx).setMessage(text).create().show();
}
}

在Web端直接调用这个方法即可:

window.NativeBridge.showNativeDialog('hello');
4.3 带回调的调用

上面已经说到了Native、Web间双向通信的两种方法,但站在一端而言还是一个单向通信的过程 ,比如站在Web的角度:Web调用Native的方法,Native直接相关操作但无法将结果返回给Web,但实际使用中会经常需要将操作的结果返回,也就是JS回调。

所以在对端操作并返回结果,有输入有输出才是完整的调用,那如何实现呢?

其实基于之前的单向通信就可以实现,我们在一端调用的时候在参数中加一个callbackId标记对应的回调,对端接收到调用请求后,进行实际操作,如果带有callbackId,对端再进行一次调用,将结果、callbackId回传回来,这端根据callbackId匹配相应的回调,将结果传入执行就可以了。

五、开源的JSBridge

实现一个完整的JSBridge是比较复杂的,需要考虑一些低端机型的兼容问题、同步异步调用问题,好在已经有开源的JSBridge供我们直接使用了:

DSBridge,主要通过注入API的形式,DSBridge for Android、DSBridge for IOS

JsBridge,主要通过拦截URL Schema,JsBridge

以DSBridge-Android为例:

// Web端代码
<body>
<div>
<button id="showBtn">获取Native输入,以Web弹窗展现</button>
</div>
</body>
// 引入SDK
<script src="https://unpkg.com/dsbridge@3.1.3/dist/dsbridge.js"></script>
<script>
const showBtn = document.querySelector('#showBtn');
showBtn.addEventListener('click', e => {
// 注意,这里代码不同:SDK在全局注册了dsBridge,通过call调用Native方法
dsBridge.call('getNativeEditTextValue', '', value => {
window.alert('Native输入值' + value);
})
});
</script>
// Android代码
// 使用dwebView替换原生webView
dwebView.addJavascriptObject(new JsApi(), null); class JSApi {
private Context ctx;
public JSApi (Context ctx) {
this.ctx = ctx;
} @JavascriptInterface
public void getNativeEditTextValue(Object msg, CompletionHandler<String> handler) {
String value = ((MainActivity)ctx).editText.getText().toString();
// 通过handler将value传给Web端,实现回调的JSB调用
handler.completed(value);
}
}

Hybrid开发是目前移动端开发的主流技术选项,其中Native和Web端的双向通信就离不开JSBridge

其中Native调用Web端是直接在JS的Context直接执行JS代码,Web端调用Native端有两种方法,一种是基于URL Schema的拦截操作,另一种是向JS的Context(window)注入Api,其中注入Api是目前最好的选择。完整的调用是双向通信,需要一个回调函数,技术实现上就是使用了两次单向通信

开源的JSBridge:DSBridge、jsBridge。

聊一聊桥接(JSBridge)的原理的更多相关文章

  1. WebView JS交互 JSBridge 案例 原理 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  2. Hybrid APP基础篇(四)->JSBridge的原理

    说明 JSBridge实现原理 目录 前言 参考来源 前置技术要求 楔子 原理概述 简介 url scheme介绍 实现流程 实现思路 第一步:设计出一个Native与JS交互的全局桥对象 第二步:J ...

  3. JSBridge的原理

    前言 参考来源 前人栽树,后台乘凉,本文参考了以下来源 github-WebViewJavascriptBridge JSBridge-Web与Native交互之iOS篇 Ios Android Hy ...

  4. Android JSBridge的原理与实现

    在Android中.JSBridge已经不是什么新奇的事物了,各家的实现方式也略有差异. 大多数人都知道WebView存在一个漏洞.见WebView中接口隐患与手机挂马利用,尽管该漏洞已经在Andro ...

  5. JSBridge通信原理, 有哪几种实现的方式?

    JsBridge给JavaScript提供了调用Native功能,Native也能够操控JavaScript.这样前端部分就可以方便使用地理位置.摄像头以及登录支付等Native能力啦.JSBridg ...

  6. jsBridge

    jsBridge https://www.dazhuanlan.com/2019/12/05/5de7eb50739df/ JSBridge的原理 https://juejin.im/post/5ab ...

  7. JsBridge实现Javascript和Java的互相调用

    前端网页Javascript和Native互相调用在手机应用中越来越常见,JsBridge是最常用的解决方案. 在Android开发中,能实现Javascript与Native代码通信的,有4种途径: ...

  8. 设计模式之桥接模式(Bridge)

    桥接模式与原理:将抽象部分与实现部分分离,使它们都可以独立的变化.最终的结果表现在实现类中.两者之间属于等价关系,即实现部分和抽象部分可以相互交换. 代码如下 #include <iostrea ...

  9. 虚拟机+桥接模式+Host-only模式 搭建完美的Windows下Linux开发环境

    相信有很多鞋童和我一个样是一枚Linux码农(我现在还是嵌入式方向). 做Linux开发势必需要一个Linux环境, 大多数开发者会首先选择一个Linux发行版, 其中Ubuntu LTS版本应该是选 ...

随机推荐

  1. 涂颜色的RPG问题

    长度为n的方格,刷3种颜色的颜料,相邻的方格颜料颜色不能相同,且首尾方格颜色不能相同.每个方格必须涂色.计算一共有多少种涂色方式. 解题思路:(1)f(1)=3,f(2)=6,f(3)=6 (2)如果 ...

  2. 51nod 1073约瑟夫环 递归公式法

    约瑟夫环问题的原来描述为,设有编号为1,2,--,n的n(n>0)个人围成一个圈,从第1个人开始报数,报到m时停止报数,报m的人出圈,再从他的下一个人起重新报数,报到m时停止报数,报m的出圈,- ...

  3. Volatile如何保证线程可见性之总线锁、缓存一致性协议

    基础知识回顾 下图给出了假想机的基本设计.中央处理单元(CPU)是进行算术和逻辑操作的部件,包含了有限数量的存储位置--寄存器(register),一个高频时钟.一个控制单元和一个算术逻辑单元. 时钟 ...

  4. 痞子衡嵌入式:超级下载算法(RT-UFL)开发笔记(4) - 轮询Flash配置参数

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是超级下载算法开发笔记(4)之轮询Flash配置参数. 文接上篇 <超级下载算法(RT-UFL)开发笔记(3) - 统一FlexSP ...

  5. React Refs All In One

    React Refs All In One https://reactjs.org/docs/react-api.html#refs Ref https://reactjs.org/docs/refs ...

  6. SPC空投价值高达310万美金,生态建设者直呼真香!

    市场上面有句名言:"人赚不到自己认知以外的财富",这在数字加密上也是共通的.早在本月12日,也就是前天,NGK官方发行的第N波利好---SPC侧链代币空投已经陆续发放了,NGK以及 ...

  7. WPF权限控制——【3】数据库、自定义弹窗、表单验证

    你相信"物竞天择,适者生存"这样的学说吗?但是我们今天却在提倡"尊老爱幼,救死扶伤",帮助并救护弱势群体:第二次世界大战期间,希特勒认为自己是优等民族,劣势民族 ...

  8. 2018-1-6-IDEA快速代码生成

    2018-1-6-IDEA快速代码生成 Java 自动生成 Intellij IDEA 利用IDEA编辑器的Live Templates可以实现自定义方法.属性.注释等,下面是我自己的常用模板. 属性 ...

  9. css优先级和权重

    1. 权重概念: 权重,是一个相对的概念,是针对某一指标而言.某一指标的权重是指该指标在整体评价中的相对重要程度. 权重系数,是表示某一指标项在指标项系统中的重要程度,它表示在其它指标项不变的情况下, ...

  10. js---it笔记

    typeof a返回的是字符串 vscode scss安装的easy scss中的配置settingjson文件中的css编译生成路径是根目录下的