年终盘点跨平台技术(Hybrid、RN、Weex、Flutter)-全栈系列
跨平台技术发展的三个阶段
第一阶段是混合开发的web容器时代
- 为了解决原生开发的高成本、低效率,出现了Hybrid混合开发
- 原生中嵌入依托于浏览器的WebView
- Web浏览器中可以实现的需求在WebView中基本都可以实现
- 但是Web最大的问题是,它的性能和体验与原生开发存在肉眼可感知的差异
- 因此并不适用于对性能和用户体验要求较高的场景
第二阶段是以RN和Weex为代表的泛web容器时代
- RN对Web标准进行了功能裁剪
- 用户体验更接近于原生了
- 由于进行了功能裁剪,所以RN对业务的支持能力还不到浏览器的5%
- 因此仅适用于中低复杂度的低交互类页面。面对稍微复杂一点儿的交互和动画需求,都需要通过调用原生代码去扩展才能实现
第三阶段是以Flutter为代表的自绘引擎时代
- Flutter是构建Google物联网操作系统Fuchsia的SDK
- 它使用Dart语言开发APP
- 一套代码可以同时运行在iOS和Android平台上
- Flutter采用自带的Native渲染引擎渲染视图,它是自己完成了组件渲染的闭环
- 而RN、Weex之类的框架,只是通过JavaScript虚拟机扩展调用系统组件,最后是由Android或者iOS系统来完成组件的渲染
下面来看一下几类型的混合开发APP:
Web APP框架
ionic
Ionic框架是基于Web技术应用HTML、CSS以及Java技术进行智能设备APP开发的框架,Ionic框架是用来开发混合模式的移动APP开发框架;
优势
- 全套的UI组件
Ionic框架很注重外观的体验,所以它提供了很多UI组件帮助开发者开发APP,比如:下拉刷新、标签等。界面美观,开发者能够很快的上手,开发的APP都很实用。 - 代码容易维护
Ionic框架是基于AngularJS,也就支持AngularJS的特点,遵循标准的代码,维护代码就很容易,能够完美融合AngularJS - 支持跨平台
可以在主流的Android操作系统和ios操作系统上运行,或者其他的操作系统也可以支持 - 很多强大的命令行
- 强大的社区、框架适用范围广
能够编译成各个平台的应用程序
劣势
- 内存占用高
- 不适合做游戏类型app
- web技术无法解决一切问题,对于比较耗性能的地方无法利用native的思维实现优势互补,如高体验的交互,动画等
Cordova
Cordova提供了一组设备相关的API;通过这组API,移动应用能够以JavaScript访问原生的设备功能,如摄像头、麦克风等;Cordova还提供了一组统一的JavaScript类库,以及为这些类库所用的设备相关的原生后台代码;Cordova支持如下移动操作系统:iOS, Android,ubuntu phone os, Blackberry, Windows Phone, Palm WebOS, Bada 和 Symbian。
通信
通信原理
- 保存Cordova_plugin.js的 插件文件名字和地址
- 插件的API呼出时,通过调用Cordova的exec模块将API的参数保存在CommandQueue的队列中。 CALLBACK则保存在JS侧的callbacks map里面
- 添加一个空的iframe,iframe的src则指向gap://ready
- 3的iframe的src设置以后,NATIVE侧UIWebviewDelegate#shouldStartLoadWithRequest则被呼出来
- Webview的Delegatet判断gap://ready的情况下,则执行commandDelegate的处理
- commandDelegate则从JS侧取出API的参数,内部实现则是通过 UIWebview#stringByEvaluatingJavaScriptFromString的返回值 取得CommandQueue里面的参数转换成JSON数据
- 根据6的插件,执行NATIVE定义的插件实例
- 插件中,有CALLBACK的情况下,成功失败的结果通过UIWebview#stringByEvaluatingJavaScriptFromString执行JS,JS端则根据传过来的CALLBACKID,从callbacks map取出回调函数并执行
通信方式
- iframe的方法(默认)
- xmlHttpRequest的方法(iOS5.x版本因为 -webkit-scroll的IFRAME有BUG,则推荐使用)
插件导入流程
Native
- APP启动,MainViewController初始化之时,queue和command的DELEGATE初期化
- config.xml文件解析,插件名设置到数组,插件文件和插件名设置到pluginMap,属性设置到setting
- 在Webview类里面,加载index.html,index.html里面加载cordova.js、开始初期化
JS
- 加载cordova.js时、内部的事件设置模块,NATIVE交互模块,初期化模块,插件加载
- 插件模块是cordova_plugins.js文件定义的插件文件地址,文件名保存的MAP
- deviceready事件发布后,插件的API可以使用了
- 插件API执行后,模块MAP将插件文件加载,执行exec函数
- 在index.html里面添加一个空的iframe、指定src=gap://ready,通知到Nativie
优势
- iOS和Android基本上可以共用代码;
- 纯web思维,开发速度快, 简单方便,一次编码,到处运行;
- 如果熟悉web开发,文档很全, 系统级支持封装较好,所有UI组件都是有html模拟,可以统一 使用;
- 可实现在线更新,允许动态加载web js;
- 文档多,开发者多,遇到问题容易解决,技术成熟;
劣势
- 占用内存高一些;
- 不适合做游戏类型app;
- web技术午无法解决一 切问题,对于比较耗能的地方无法利用native的思维实现优势互 补,如高体验的交互,动画等。
Hybrid APP(Webview)
利用 安卓和 iOS 上的 webview 容器,APP 能够执行 html、css 和 js 脚本,展示 web 页面。如果需要原生功能就添加 bridge 供 java 调用。具有开发效率高、跨平台、支持动态发布等特点,它是目前应用最广泛最成熟的一种方案;
Webview通信
假跳转的请求拦截(不建议)
- 假跳转的请求拦截 就是由网页发出一条新的跳转请求,跳转的目的地是一个非法的压根就不存在的地址
- 比如:wbcst://testhost/action?params=xxx
- 模拟http协议网络请求 scheme://host/action?params
- 客户端会无差别拦截所有请求,真正的url地址应该照常放过,只有协议域名匹配的url地址才应该被客户端拦截
- JS调用方式
- a标签跳转
- location.href跳转
- iframe跳转
- 不建议使用,android系统对url参数做了字节限制,无法进行大数据的通信
弹窗拦截(不建议)
- alert
- 弹出个提示框,只能点确认无回调
- confirm
- 弹出个确认框(确认,取消),可以回调
- prompt
- 弹出个输入框,让用户输入东西,可以回调
- 不建议使用,会无差别的拦截所有前端的window弹窗
- alert
JS上下文注入(推荐)
- iOS
- WKWebView scriptMessageHandler注入
- android
- addJavascriptInterface注入
- 特点
- 不通过任何拦截的办法,而是直接将一个native对象(or函数)注入到JS里面,可以由web的js代码直接调用,直接操作
- iOS
WebView 渲染引擎设计的上的缺陷
- JS Execute,Layout, Paint 都在MainThread ,无法并行化。
- JS 的性能赶不上 Native Tookit 的 Java Dart Object-C 等编译型语言,执行复杂逻辑时会卡顿。
- 渲染流水线非常长,导致浏览器对合成器动画和非合成器动画区分对待,非合成器动画性能不佳。
- OpenGL 设计上是推荐单线程模型,一个 Context 同时只能运行一个线程使用。 GPU Thread 运行在单独 GPU 进程, Render 进程无法访问 GPU 进程的 OpenGL Context ,两个进程无法 Texture 共享资源。 Render 进程只能输出 Bitmap/Command Buffer 通过 IPC 传递给 GPU 进程,无法直接在 GPU 进程的 Open GL Context 做直接光栅化,难以充分发挥现代 GPU 的性能。
- 光栅化是异步进行的,进行惯性滚动时,会出现白屏,这个是 Webview 始终无法避免的问题。
- 设备平台众多,需要兼容CPU渲染,无法进行 All In GPU 的设计。
优势
- 跨平台
- 开发周期短、成本低
- 用户体验良好
- 可以即时修复bug、动态发版
劣势
- 仿原生iOS效果复杂
- 机型兼容性
ReactNative/Weex跨平台技术
这种技术最大化的复用前端的生态和 Native 的生态体系,把 Native View 的高性能组件积累输出给前端的技术体系。此方案和浏览器的最大区别在于 Script 的执行和 Native View 渲染体系。
ReactNative
通信流程(OC)
- ①js调用OC模块暴露出来的方法
- ②把调用方法分解为ModuleName、MethodName、arguments,在丢给MessageQueue处理
- ③把js的callback函数缓存在MessageQueue的一个成员变量里面,同时生成一个CallbackID来代表callback;在通过保存在MessageQueue的模块配置表把ModuleName、MethodName转成ModuleID、MethodID
- ④把ModuleID、MethodID、CallbackID和其他参数传给OC(JavaScriptCore)
- ⑤OC接到消息,通过模块配置表拿到对于的模块和方法
- ⑥RCTModuleMethod对js传过来的参数进行处理
- ⑦OC模块方法执行完,执行block回调
- ⑧调用第6步中RCTModuleMethod生成的block
- ⑨block带着CallbackID和block传过来的参数去掉用js里的MessageQueue方法invokeCallbackAndReturnFlushedQueue
- ⑩MessageQueue通过CallbackID找到相应的js的callback方法
- ⑪调用callback方法,并把OC带过来的参数一起传过去完成回调
优势
虽然不能做到一次编码到处运行,但是基本上即使是两套代码, 也是相同的jsx语法, 使用js进行开发。用户体验高于html, 开发效率较高
Flexbox布局据说比native的自适应布局更加简单高效
劣势
对开发人员要求较高,不是懂点web技术就行的,当官方封装的 控件、API无法满足需 求时就必然需要懂一些native的东西去 扩展,扩展性仍然远远不如web,也远远不如直 接写Native Code。
Weex
实现原理
Weex 对外通过 Rax 和 Vue 前端框架进行功能输出,前端框架下有一层 JS Framework 来实现 dom 的功能。 WeexCore 负责基础的 Flex Layout ,然后通过 Component 分别对接到 Android/iOS 的 Platform Native View 体系。
优势
- Android Native 采用更轻量级的渲染流水线,能更快更高效的的响应事件;
- RenderThread 直接操作 OpenGLContext ,进行 Direct GPU Raster ,充分发挥现代 GPU 的特性,提供高性能渲染和流畅的体验;
- 部分耗时操作,如 Bitmap 上传 Texture , TextureThread 上传到 Share Open GL Context 中, Texture 完成后通知主线程进行绘制,通过 Share Open GL Context 与主线程共享 Texture 等资源。 WebView 只能在 Render Process 内部进行 Texture 的共享, RenderProcess 无法与 GPU Process 共享 Texture 等资源;
- Android Native 有 RecycleView ViewPager 等高级组件,每个高级组件都做了性能的最佳实践;浏览器上的高级组件只能通过 JS 模拟实现,优化定制效率低;
- 浏览器流水线设计复杂,需要考虑到 PC 、手机、嵌入式设备等多种复杂的环境,不少设备上木有 GPU ,只能进行 CPU 渲染。无法像 Android Native 体系一样进行 All In GPU 的体系设计,全面发挥现代 GPU 的性能。
劣势
Weex 体系充分将 Native 的 View 体系输出到前端体系中,在进行 Android/iOS Native View 的封装过程中,存在不少难以逾越的障碍
Flutter自绘引擎
Flutter是Google发布的一个用于创建跨平台、高性能移动应用的框架。Flutter和QT mobile一样,都没有使用原生控件,相反都实现了一个自绘引擎,使用自身的布局、绘制系统
框架
基础架构主要分为三个部分:
Framework
- 纯 Dart实现的 SDK,类似于 React在 JavaScript中的作用
- 它实现了一套基础库, 用于处理动画、绘图和手势
- 基于绘图封装了一套 UI组件库
- 根据 Material 和Cupertino两种视觉风格区分开来
Engine
- 纯 C++实现的 SDK
- 包括
- Skia引擎
- Dart运行时
- 文字排版引擎等
- 它是 Dart的一个运行时,它可以以 JIT 或者 AOT的模式运行 Dart代码
- 这个运行时还控制着 VSync信号的传递、GPU数据的填充等,并且还负责把客户端的事件传递到运行时中的代码
Embedder
- Embedder是操作系统适配层
- 实现了
- 渲染Surface设置
- 线程设置
- 平台插件等平台相关特性的适配
渲染流程
- GPU的VSync信号同步给到UI线程
- UI线程使用Dart来构建抽象的视图结构(这里是Framework层的工作)
- 绘制好的抽象视图数据结构在GPU线程中进行图层合成(在Flutter Engine层的工作)
- 然后提供给Skia引擎渲染为GPU数据,最后通过OpenGL或者 Vulkan提供给 GPU
优势
高生产效率。一套代码可以开发出Android和iOS应用;Dart语 言优越性,使得同样的 功能只需要很少的代码;迭代更加方便, hot reload功能;
创建优雅的、高度可定制的用户界面。Flutter内置了对Material Design和Cupertino(iOS-favor)的UI组件库;提供了可定制 的UI组件,不再受制于OEM控件的限制;
借助可移植的GPU加速的渲染引擎以及高性能本地ARM代码运行 时以达到跨平台的高质量用户体验。
劣势
Flutter采用Dart语言开发,属于小众语言,需要一切都要重新 学习。
横向对比
对比内容 | ReactNative | weex | Flutter | Hybrid |
---|---|---|---|---|
平台实现 | JavaScript | JavaScript | 原生编码 | H5 |
引擎 | JSCore | JS V8 | Flutter Engine | Webview |
核心语言 | React | Vue | Dart | JavaScript |
打包bundle文件 | 默认单一文件比较大(可拆包) | 较小,多页面多文件 | 不需要 | 前端JS、CSS一般CDN引用 |
跨平台 | 中 | 中 | 中上 | 上 |
热更新 | 好 | 好 | 暂无方案 | 好 |
性能 | 中 | 中 | 中上 | 差 |
年终盘点跨平台技术(Hybrid、RN、Weex、Flutter)-全栈系列相关推荐
- 移动互联网这十年,跨平台技术的演进及 Flutter 的未来
作者 | 袁辉辉 责编 | 郭 芮 移动跨平台技术演进 1. 引言 移动互联网发展十余年,伴随着 Android.iOS 等智能手机的不断普及,移动端已逐步取代 PC 端,成为兵家必争之地.正所谓 ...
- Serverless + 低代码,让技术小白也能成为全栈工程师?
导语 | Serverless 发展至今,孵化出越来越多融合 Serverless 理念的产品,在丰富了 Serverless 产品矩阵的同时,也反哺和拓展着整个生态:从基础底层的 IaaS,到 Fa ...
- java产品经理_产品经理必懂的技术那点事儿:成为全栈产品经理
资料目录: 1 产品思维与技术思维 1 1.1 产品经理为什么要懂技术 1 1.2 产品经理和工程师分别是干什么的 3 1.3 产品设计中需要注意的技术边界 5 1.4 工程师的 ...
- IT界6个国内技术大牛博客,全栈工程师修行的秘籍!
今天就为大家推荐我认为比较不错的6个技术大牛博客,大家有兴趣可以关注一下,看看大牛们的编程思路,学习他们思考问题的方法,不多说废话,开始我们的话题吧! 风雪之隅-Laruence的博客 Laruenc ...
- Python 全栈系列196 全栈技术梳理
说明 梳理一下目前的技术组件. 内容 1 Web服务器 Tornado的网络处理能力还是比Flask要快3倍左右的 1 Flask + Gevent 2 Tornado 项目地址 文章1 五种模式对比 ...
- 推荐6个国内技术大牛博客,全栈工程师修行的秘籍!(建议收藏)
学习PHP语言.JavaScript语言.Python语言及前端的知识点,光是自己学习还是不够的,我们还要借鉴大牛们的编程思路,了解编程的技巧和方法,这样才能事半功倍. 今天就为大家推荐我认为比较不错 ...
- jmeter中重定向多个正则表达式_2020年jmeter技术实战续集,最新技术全栈,值得收藏
在上一篇:主要介绍线程组.HTTP请求默认值.用户定义的变量.固定定时器的应用场景及实战. 以下主要介绍正则表达式提取器.调式取样器(Debug Sampler).响应断言.HTTP信息头管理器的应用 ...
- 最火移动端跨平台方案盘点:React Native、weex、Flutter
本文原文由"恋猫月亮"原创发布,原题为<移动端跨平台开发的深度解析>,本次重新整理后,为了优化阅读体验,内容略有改动,感谢原作者的无私分享. 1.前言 跨平台一直是老生 ...
- 跨平台开发技术年终盘点
一直以来,效率都是互联网企业的生命线.而"通过技术升级实现三个人干五个人的活,赚四个人的工资"是企业和个人一直渴望达到的双赢局面. 随着行业竞争加剧,为进一步提升开发效率,跨平台开 ...
最新文章
- 【Flask】路由和URL
- 计算机科学与技术专业机遇与挑战,科学网—填报专业大类志愿:机遇与挑战 - 雒运强的博文...
- Javascript动态执行问题浅析
- 丘成桐中学计算机科学奖,丘成桐中学科学奖
- 刷网课会被检测出来吗_目标检测中的Precision和Recall
- Kubernetes (federation)联邦机制介绍
- 21种网页在线客服代码实例演示
- 计算机专业人才需求调研背景,计算机专业人才需求调研报告
- 魔兽十区服务器人最多,十区毁灭计划 新一轮wow大服务器实装公告
- Java虚拟机之堆空间
- html中图片左右切换,超简单的图片左右切换滑动
- 关于MMORPG多人对战中热点问题的解决思路讨论
- [附源码]java毕业设计家政管理系统
- skimage中的图像直方图均衡化
- Google Chrome 66可以下载啦
- 【方法】如何快速高效学习
- python中引号的使用规范_Python中单引号和双引号的作用
- 某银行存储瘫痪、缺失6个小时数据,只能人工补录
- 云集群搭建-创建阿里云实例
- miui 8.2 android版本下载,小米日历apk 8.0下载