Hybrid-APP技术原理

源宝导读: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 的微服务运行情况监控实践

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/305586.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于微软ASP.NET AJAX框架开发幻灯片播放网页

一、 简介 最近,微软ASP.NET Ajax 1.0框架以其完整的基于Ajax的web开发方案呈现在web技术人员的前面,凭借与遗留ASP.NET系统的有机整合以及完全面向对象的客户端JavaScript组件模型两大绝杀正在引起越来越多的基于.NET平台的web开发者的关注。本文应该属…

推荐:.Net 5开源免费的内容管理系统

背景介绍内容管理系统(content management system,CMS)是一种位于WEB 前端(Web 服务器)和后端办公系统或流程(内容创作、编辑)之间的软件系统。内容的创作人员、编辑人员、发布人员使用内容管理…

河南信息工程学校计算机组装比赛,计算机技术系承办2019全员化试点项目计算机网络装调赛项...

2019年10月16日,由河南省教育厅主办、河南省职业教研室承办的技能竞赛全员化试点项目“计算机网络装调”赛项在河南信息工程学校开赛,来自全省37所学校的96名选手同台竞技,和谐交流。“计算机网络装调”赛项是2019年河南省中职教育技能竞赛的…

限制IIS站点的内存,避免级联影响

背景 代码写的有问题,会很容易出现内存泄露的问题。应用如果是部署在docker容器里面的,可以限制这个应用的内存。那么,如果是传统的.NET Framework应用,部署在IIS上面呢?老黄曾经遇到过在一台服务器上面,II…

笔记本怎么查看hdmi版本_涨知识丨一文看懂笔记本电脑HDMI接口

上一期文章我们同大家简单介绍了笔记本电脑Type-C接口及其日常用途,今天我们来聊聊笔记本电脑上另一个常备的电脑接口HDMI,它究竟是什么,有哪些用途,我们一一为您揭晓!如图所示,有着HDMI标识的接口就是我们…

中小企业CRM评测-用户交互_易客

用户交互<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />如何评测在这个部分我们应用了用户接口易用性方面的几种测试方法&#xff0c;以客观的评估参测产品在用户接口设计方面的素质。物理操作负担主要是由参测产品完成一组既定…

pdf编辑软件adobe acrobat_分享一款PDF编辑和阅读软件Acrobat

Adobe Acrobat介绍是一款非常好用且功能强大的PDF编辑和阅读软件。可以对PDF文件进行查看、添加注释、填写、签名并发送之外&#xff0c;同时还可以使用一些高级工具来创建、编辑、导出和组织PDF&#xff0c;以及将任何内容转换为高质量的PDF&#xff0c;并在任何屏幕上完美呈现…

诈尸了。不瞒您说,老坑从不填,天天开新坑

诈尸了。你的年更 UP 诈尸了。不瞒您说&#xff0c;我其实有好多乱七八糟的东西想往外捯饬捯饬整理整理。写过博客&#xff0c;发过公众号&#xff0c;做过视频。但是这些对我整理分享知识来说都有一个硬伤&#xff1a;慢。而咱们 IT 工作者&#xff08;哦&#xff0c;还有培训…

打开计算机任务栏有桌面没,电脑桌面任务栏不显示打开的窗口怎么办

我们在使用电脑的时刻&#xff0c;会遇到林林总总的问题&#xff0c;有时刻我们就会遇到我们在桌面打开了一个页面&#xff0c;然则电脑桌面下方的任务栏却不显示打开的窗口&#xff0c;那这是怎么回事呢&#xff1f;我们想要任务栏显示打开的窗口又该怎么做呢&#xff1f;今天…

Visual Studio将原生支持WSL 2

喜欢就关注我们吧&#xff01;近日&#xff0c;微软官方宣布旗下的集成开发环境 Visual Studio 将原生支持 WSL 2&#xff0c;这意味着 VS 用户可以在 WSL 2 上进行无缝构建和调试&#xff0c;而无需添加 SSH 连接&#xff0c;提升运行效率。据悉&#xff0c;微软曾在 2019 年将…

python删除符合条件的行_这十道经典Python笔试题,全做对算我输

经常有小伙伴学了Python不知道是否能去找工作&#xff0c;可以来看下这十道题检验你的成果&#xff1a;1、常用的字符串格式化方法有哪些&#xff1f;并说明他们的区别a. 使用%&#xff0c;语法糖print("我叫%s&#xff0c;今年%d岁" % ("oxs", 18)) # 我叫…

springmvc如何使用视图解析器_SpringMVC工作原理

SpringMVC工作原理图&#xff1a;SpringMVC流程1、 用户发送请求至前端控制器DispatcherServlet。2、 DispatcherServlet收到请求调用HandlerMapping处理器映射器。3、 处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找)&#xff0c;生成处理器对象及处理器拦截器(…

你有把依赖注入玩坏?

【导读】自从.NET Core给我们呈现了依赖注入&#xff0c;在我们项目中到处充满着依赖注入&#xff0c;虽然一切都已帮我们封装好&#xff0c;但站在巨人的肩膀上&#xff0c;除了凭眺远方&#xff0c;我们也应平铺好脚下的路使用依赖注入不仅仅只是解耦&#xff0c;而且使代码更…

mysql 表与表之间的条件比对_值得收藏 | 一份最完整的MySQL规范

一、数据库命令规范所有数据库对象名称必须使用小写字母并用下划线分割所有数据库对象名称禁止使用MySQL保留关键字(如果表名中包含关键字查询时&#xff0c;需要将其用单引号括起来)数据库对象的命名要能做到见名识意&#xff0c;并且最后不要超过32个字符临时库表必须以tmp_为…

asp.net core服务中的限流

使用了AspNetCoreRateLimit三方库&#xff0c;starup.cs配置如下。using AspNetCoreRateLimit; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Configuration; using Microsoft.Exte…

sublime text html乱码,Sublime Text 2中文显示乱码的解决方法

Sublime Text 2中文显示乱码的解决方法发布时间&#xff1a;2014-05-12 15:30:14 作者&#xff1a;佚名 我要评论这篇文章主要介绍了Sublime Text 2中文显示乱码的解决方法,需要的朋友可以参考下1、安装Sublime Package Control。在Sublime Text 2上用Ctrl&#xff5e;打开…

2020 中国开源年度报告

点击上方“开源社”关注我们| 编辑&#xff1a;沈于蓝1前言撰写这篇前言&#xff0c;我们的心情一直很复杂&#xff0c;很难用某种词汇来概括。在心里升起的一句话是&#xff1a;“这是最好的时代&#xff0c;这是最坏的时代”。也许多年以后&#xff0c;我们回看 2020 年&…

python实验总结心得体会_Python,Pyvisa操作Agilent 86140x系列OSA

1&#xff0c;背景本人做光学的。。。最近研究实验偏向通信做WDM实验的时候发现能用实验室TCP/IP通信的光谱仪(OSA)都被用了&#xff0c;翻翻找找只在角落找到一台Agilent 68146B的OSA。。。就是下图这个货&#xff0c;想要捞取光谱数据&#xff0c;你看到那个软盘接口了吗。。…

cgcs2000高斯平面直角坐标_如何巧妙记忆高斯积分

高斯积分作为一种特殊的反常积分&#xff0c;其应用范围相当广泛&#xff0c;无论是在概率论中所引入的高斯分布&#xff08;亦称正态分布&#xff09;&#xff0c;还是在统计物理中的相关应用&#xff0c;都表明其有着至关重要的作用。下面我们来介绍一种记忆高斯积分的方法&a…

基于.NET Core的优秀开源项目合集

开源项目非常适合入门&#xff0c;并且可以作为体系结构参考的好资源, GitHub中有几个开源的.NET Core项目&#xff0c;这些项目将帮助您使用不同类型的体系结构和编码模式来深入学习 .NET Core技术, 本文列出了不同类别的优秀的开源项目。???? eShopOnContainerseShopOnCo…