源宝导读:Hybrid-APP技术不仅具有“Native APP的良好交互体验”同时也具备“Web APP跨平台开发的优势”。既然Hybrid-APP有这么多优势,那么究竟什么样的APP才算Hybrid App呢?本文将分享我们的技术研究成果。

一、什么是Hybrid-APP

  • 狭义的Hybrid:

    • 也是现在大家普遍认知的,Hybrid就是一种给 WebView 增加一些js通信可以调用原生API的方式。

  • 广义Hybrid:

    • 前端的开发思路与客户端原生的开发思路相结合。

    • 通过原生的配合,把原本js or 前端开发做不到的事情做到了,用原生的方式增强了原本的前端技术能力。

    • WebView+Bridge、RN、weex、小程序。

我能否认为,只要是前端的开发思路与客户端原生的开发思路相结合,就认为他是一种Hybrid?
    通过原生的配合,把原本js or 前端开发做不到的事情做到了,用原生的方式增强了原本的前端技术能力,是否就是一种 Hybrid?
    无论是WebView+Bridge也好,RN类似的原生渲染框架也好,小程序也好,某种意义上讲,他们都算Hybrid?

Hybrid框架-基本能力

接下来我们来看一下,一个Hybrid框架所需要具备的基本能力:

  • 跨平台能力。

这也是Hybrid应用与原生应用相比最大的优点,一次编写随处运行。

  • 灵活的业务模块扩展能力。

  • 良好的调用原生功能的能力。

由于在APP中有些功能必须由原生端提供,所以还需要有良好的调用原生功能的能力。

  • 快速更新迭代的能力。

使用原生技术开发的APP每次更新都需要上传应用商店审核,但是使用Hybrid技术开发的应用可以绕过应用商店实现热更新。

二、Hybrid-APP中通信方案

在Hybrid APP中最核心的技术就在于前端与客户端如何通信,接下来我们看一下,js与native之间是如何通信的。

2.1、JS 调用 Native 的几种方法

  • 假跳转的请求拦截

    1. A标签跳转。

    2. 原地跳转。

    3. iframe跳转。

  • 弹窗拦截

    1. alert()

    2. prompt()

    3. confirm()

  • JS上下文注入

    1. 苹果JavaScriptCore注入。

    2. 安卓addJavascriptInterface注入。

    3. 苹果scriptMessageHandler注入。

2.2、Native 调用 JS 的几种方法

  • evaluatingJavaScript 直接注入执行JS代码

JS是一个脚本语言,任何一个JS引擎都可以在任意时机直接执行JS代码,我们可以把任何Native想要传递的消息/数据直接写进JS代码中。

  • loadUrl 浏览器用’javascript:’+JS代码做跳转地址

在浏览器中,可以直接用’javascript:xxxx’来简单的执行一些JS代码,这个方法只有安卓可以用,因为iOS必须先将url字符串生成Request再交给webview去load

  • WKUserScript WKWebView的 addUserScript 方法

WKWebView官方提供了一个Api,可以让WebView在加载页面的时候,自动执行注入一些预先准备好的JS

2.2.1、假跳转的请求拦截

假跳转的请求拦截 就是由网页发出一条新的跳转请求,跳转的目的地是一个非法的压根就不存在的地址。

url地址由协议、域名、路径、参数这么几个部分构成,我们可以构建一条假的url:用协议与域名当做通信识别、用路径当做指令识别、用参数当做数据传递。

客户端会无差别拦截所有请求,真正的url地址应该照常放过,只有协议域名匹配的url地址才应该被客户端拦截,拦截下来的url不会导致webview继续跳转错误地址,因此无感知,相反拦截下来的url我们可以读取其中路径当做指令,读取其中参数当做数据,从而根据约定调用对应的native原生代码。

  • JS发起调用

JS其实有很多种方式发起假请求,跟发起一个新请求没啥两样,只要按协议约定 生成假请求地址,正常的发起跳转即可,任何一种方式都可以让客户端拦截住。

  • 客户端拦截

    1. 安卓的拦截方式:shouldOverride UrlLoading。

    2. UIWebView的拦截方式:webView: shouldStartLoadWithRequest :navigationType。

    3. WKWebView的拦截方式:webView: decidePolicyForNavigationAction :decisionHandler。

2.2.2、弹窗拦截

  • JS发起调用

可以使用alert/confirm/prompt三种弹框,每种弹框都可以由JS发出一串字符串,用于展示在弹框之上,而此字符串恰巧就是可以用来传递数据,我们把所有要传递通讯的信息,都封装进入一个js对象,然后生成字典,最后序列化成json转成字符串。

  • 客户端拦截

    1. 安卓的拦截方式:onJsPrompt。

    2. UIWebView的拦截方式:不支持截获任何一种弹框。

    3. WKWebView的拦截方式:webView: runJavaScriptText InputPanelWith Prompt :balbala。

2.2.3、苹果UIWebview JavaScriptCore注入

  • 客户端注入

UIWebView可以通过KVC的方法,直接拿到整个WebView当前所拥有的JS上下文documentView.webView.mainFrame.javaScriptContext。
    拿到了JSContext,一切的使用方式就和直接操作JavaScriptCore没啥区别了,我们可以把任何遵循JSExport协议的对象直接注入JS,让JS能够直接控制和操作。

  • JS调用

在没经过客户端注入的时候,直接使用调用callNativeFunction()会报 callNativeFunction is not defined这个错误,说明此时JS上下全文全局,是没有这个函数的,调用无效。
  在执行完客户端注入后,此时JS上下文全局对象下面,就拥有了这个callNativeFunction的函数对象,就可以正常调用,从而传递数据到Native。

2.2.4、安卓addJavascriptInterface注入

  • 客户端注入

安卓的WebView有一个接口addJavascriptInterface,可以在loadUrl之前提前准备一个对象,通过这个接口注入给JS上下文,从而让JS能够操作,这个操作方式很类似苹果UIWebview JavaScriptCore注入,整个机制也差别不大。

  • JS调用

在android端注入的对象同样也被挂载在JS上下文全局对象下面,直接访问即可调用。

2.2.5、苹果WKWebView scriptMessage Handler注入

  • 客户端注入

苹果在开放WKWebView这个性能全方位碾压UIWebView的web组件后,也大幅更改了JS与Native交互的方式,提供了专有的交互APIscriptMessageHandler
需要注意的是如果当前WebView没用了,需要销毁,需要先移除这个对象注入,否则会造成内存泄漏,WebView和所在VC循环引用,无法销毁。

  • JS调用

这里不像前边两个注入一样,直接注入到JS上下文全局对象里,addScriptMessageHandler方法注入的对象被放到了,全局对象下一个Webkit对象下面。
    并且调用方式和之前的两种方法也不同,前两种都可以让js任意操作所注入自定义对象的所有方法,而addScriptMessageHandler注入其实只给注入对象起了一个名字nativeObject,但这个对象的能力是不能任意指定的,只有一个函数postMessage。

2.2.6、evaluatingJavaScript 执行JS代码

前面也简单介绍了一下,JS是一个脚本语言,可以在无需编译的情况下,直接输入字符串JS代码,直接运行执行看结果,这也是为什么在Chrome里,在网页运行的时候打开控制台,可以输入各种JS指令的看结果的。

也就是说当Native想要调用JS的时候,可以由Native把需要数据与调用的JS函数,通过字符串拼接成JS代码,交给WebView进行执行。

Android/iOS-UIWebView /iOS-WKWebView,都支持这种方法,这是目前最广泛运用的方法。

2.2.7、loadUrl 执行JS代码

安卓在4.4以前是不能用evaluatingJavaScript 这个方法的,因此之前安卓都用的是webview直接loadUrl,但是传入的url并不是一个链接,而是以”javascript:”开头的js代码,从而达到让webview执行js代码的作用。

2.2.8、WKUserScript 执行JS代码

对于iOS的WKWebView,除了evaluatingJavaScript,还有WKUserScript这个方式可以执行JS代码,他们之间是有区别的,这个虽然是一种通信方式,但并不能随时随地进行通信。

  • evaluatingJavaScript 是在客户端调用的时候js端会立刻执行代码。

  • WKUserScript 是预先准备好JS代码,当WKWebView加载Dom的时候,执行当条JS代码。

2.3、JS主动调用Native的方案对比

三、cordova运行原理

在了解了Hybrid app核心的通信方案之后,我们接下来看看目前公司使用最广泛的跨平台技术cordova的运行原理是怎么样的。

3.1、客户端入口

这里客户端以Android端为例分析,Android端默认的入口是mainActivity类,我们可以看到它其实继承CordovaActivity类,一切初始化条件是从loadUrl方法开始。

3.2、Android端核心类CordovaActivity

CordovaActivity内依赖一个WebView类,一个Preferences类,一个CordovaInterface接口,并同时初始化一些配置信息。WebView具体实现是由CordovaWebViewImpl类,CordovaInterface接口具体实现是由CordovaInterfaceImpl类实现。

CordovaWebViewImpl是核心类,里面会把一些插件能力初始化,用一个PluginManager进行管理,包含一个引擎类—CordovaWebViewEngine,这个引擎是通过反射的方式创建,自身初始化的时候把NativeToJsMessageQueue关联起来,里面包含着以Js字符串为主的双向链表,把每次从前端通过JS代码存储起来,然后通过绑定的桥接方式Pop出到相应的Native代码中去。

最终实现由SystemWebViewEngine类来对Android系统中WebView控件进行二次包装,这个类的初始化是在CordovaWebViewImpl类反射创建,相关插件和消息传递也是通过SystemWebViewEngine进行绑定。

3.3、JS端cordova初始化

Android端调用loadUrl后会启动webview加载前端代码,首先会加载运行cordova.js中的代码,在cordova.js中会运行cordova/init模块对cordova进行一个初始化,初始化中主要的核心操作就是:检查监听核心事件是否触发、平台初始化工作、加载插件js。

3.4、JS端平台启动处理

不同的平台中平台启动处理的模块会有一些差异,但是核心处理相差不大,在Android平台中主要进行了三个处理:初始化通信模块、处理物理按键的事件、在onCordovaReady事件被触发时通知原生端展示webview。

3.5、JS端插件加载处理

插件js加载处理中主要先会通过load方法加载cordova_plugins.js,获取到项目中用到的插件,然后通过injectScript方法加载插件js,可以看到整个加载过程都是通过添加script标签进行加载的,所以一旦插件数量很多对加载速度会有一定的影响。

这里只是加载插件的js代码,原生端的插件加载并不是在这里进行的。

3.6、Cordova启动流程

最后来总结一下整个cordova的启动流程,主要做了三个大的事情:

  • 原生端启动webview加载前端代码。

  • 初始化插件。

  • 建立通信通道。

3.7、Cordova通信流程

启动cordova后,在项目运行的过程中当前端需要调用native的能力时,就需要与native端进行通信,Cordova通信流程中主要有这么几点:

  • Cordova通过在原生端与js端维护两个消息队列来处理消息回调。

  • Cordova在执行完exec()后,android会马上从消息队列中取出数据同步返回,但不一定就是该次请求的数据。

  • js端通过轮询获取原生端消息队列中的数据。

四、总结

Hybrid 的宗旨就是,如果 WebView 本身做不到,或者做起来有很大限制或者性能不佳,那么可以让原生配合,一起做到。

因为Hybrid本是一个面向业务服务的东西,如果业务的野心足够大,WebView 容器的想象空间应该是在能力上与RN/小程序看齐的,WebView 在 Hybrid 的支持下,不单纯是使用Bridge 调用几个原生 API 的事。

我们完全可以拆解RN中的每个环节,把RN号称比 WebView 好的原生渲染/原生组件拆解融入 WebView,我也可以学习小程序保持 WXML/WXSS的开发方式,而非RN那样统一用JSX开发。

这种拆解不是将所有框架优点塞在一个大而全的框架中,各种优化方案的选择背后一定带来的是一些取舍。谁来决定取舍,业务决定,如果自己能深度把握这里面的设计思想,就不用在乎什么新的轮子新的框架,取其设计优点,融入自己的业务之中即可。

------ END ------

作者简介

李同学: 前端研发工程师,目前负责天际移动平台的相关研发工作。

也许您还想看

微前端架构在容器平台的应用

前端数据层落地实践

移动建模平台元数据存储架构演进

AI云店小程序演变之路

基于 Go 的微服务运行情况监控实践

Hybrid-APP技术原理相关推荐

  1. Hybrid App技术批量制作APP应用与跨平台解决方案

    Hybrid App技术批量制作APP应用与跨平台解决方案 参考文章: (1)Hybrid App技术批量制作APP应用与跨平台解决方案 (2)https://www.cnblogs.com/aaro ...

  2. [技术前沿]Hybrid App

    转 百度百科 转至 2016年5月24日 By Paul + 简介 "云"时代的来临正在改变App和运营团队之间的关系,一场不能避免的变革正在进行.鉴于移动终端的局限性,移动终端上 ...

  3. Hybrid App开发模式

    Hybrid App(混合模式移动应用)是指介于web-app.native-app这两者之间的app,兼具"Native App良好用户交互体验的优势"和"Web Ap ...

  4. 3个最基础的APP技术框架

    不知道大家有没有遇到过这种情景,当你做好一个设计方案,满心欢喜地给开发讲解方案的思路和创意时,开发突然说一句:"这个方案实现不了",这时你整个人都不好了,心里开始嘀咕"这 ...

  5. Hybrid APP 混合开发经验总结《三》

    Hybrid App技术批量制作APP应用与跨平台解决方案 隐藏导航章节导航 1. 前言 2. 定位 3. web App优势 4. 无编程开发 5. 我们可以看看设计者的一个编辑界面,基本offic ...

  6. Hybrid App 发展史

    目录 1 概述 2 Cordova 平台 3 Web 发展史 3.1 静态网页 3.2 动态网页 3.3 客户端异步交互 3.4 开发效率提速阶段 3.5 移动平台 4 Hybrid App 分类一 ...

  7. 你得知道这3个最基础的APP技术框架

    出处:优设网 作者:信籽 链接:http://www.uisdc.com/3-basic-app-technical-framework 信籽(手淘设计师):不知道大家有没有遇到过这种情景,当你做好一 ...

  8. [转]iOS hybrid App 的实现原理及性能监测

    转自:http://www.cocoachina.com/ios/20151118/14270.html iOS hybrid App 的实现原理及性能监测 2015-11-18 11:39 编辑:  ...

  9. 跨平台 webapp 开发技术之 Hybrid App

    前所知的 APP 开发模式有三种: 基于操作系统运行的 APP -> Native App,侧重于原生开发,用户体验好,需要安装才会升级 基于浏览器运行的 APP -> Web App,侧 ...

  10. 干货|app自动化测试之Appium WebView 技术原理

    混合应用测试或微信小程序测试,都会涉及到 WebView 组件,这节内容将分析一下 WebView 的技术原理.首先通过日志分析查看 Appium 的运行过程. WebView日志分析 要想查看 Ch ...

最新文章

  1. 使用Java JdbcTemplate对mySQL进行CRUD增删改查操作
  2. SAP Fiori里的List是如何做到懒加载Lazy load的
  3. 第六节:又一种新的数据类型:元组Tuple
  4. mysql limit 越大越慢_mysql 优化之14:php mysql limit 分页优化,页面值越大查询越慢...
  5. 〔总结〕容易遗忘的JS知识点整理
  6. 从零基础入门Tensorflow2.0 ----八、39.5. gpu5
  7. rbw数字信号处理_基于FPGA的数字中频信号处理的设计与实现
  8. RS485总线传输协议
  9. 深入贯彻落实 Activity 的四种启动模式
  10. 推免生是否抢了考研生的“奶酪”
  11. 趋势科技移动客户端病毒报告
  12. c语言编程统计学生个数,c编程统计并显示500至800之间所有素数的总个数以及总和...
  13. 自定义View将圆角矩形绘制在Canvas上
  14. 《管理长歌行》—— 小花狗的错误
  15. 易优EyouCMS手机端url路径改为/mobile/方案(非自带m.xxx.com二级域名方案)
  16. JavaScript异步与同步解析
  17. strcpy与strncpy的实现
  18. Mulesoft自学教程(含文档,AnypointStudio开发工具资料)
  19. GIS教程之将栅格数据 raster data发布到 Web 的 3 个简单步骤
  20. 计算机课程教材审读意,教材审读意见怎么写

热门文章

  1. Oracle数据库查询用 where in 查询的项超过1000条的解决方案
  2. Bootstrap入门(八)组件2:下拉菜单
  3. 【转】学会这13个原则写UI界面文案,用户才能秒懂
  4. 在 Visual Studio 2010 中创建 ASP.Net Web Service
  5. Theano3.2-练习之数据集及目标函数介绍
  6. 项目手札2---关于分页显示时地址栏的风格
  7. JavaScript自动设置IFrame高度(兼容各主流浏览器)
  8. SVN的VS.NET插件——AnkhSVN
  9. 短语密码_使用密码短语以提高安全性
  10. 为您的Blogger博客设计一个美丽的新主题