跨平台开发技术解析
目录
-
原生开发,优势与痛点分析
-
Android系统架构
-
iOS系统架构
-
跨平台开发的目的&&主流技术
-
移动端主流跨平台技术介绍
5.1 Flutter
5.2 ReactNative
5.4 Hybrid App
5.5 小程序
-
案例
原生开发
Native App是一种基于智能手机本地操作系统如iOS、Android、WP并使用原生程式编写运行的第三方应用程序,也叫本地app。一般使用的开发语言为Java、C++、Objective-C。Native App因为位于平台层上方,向下访问和兼容的能力会比较好一些,可以支持在线或离线,消息推送或本地资源访问,摄像拨号功能的调取。
优势
- 相比于其它模式,提供最佳的用户体验,最优质的用户界面,最华丽的交互;
- 针对不同平台提供不同体验;
- 可节省带宽成本,打开速度更快;
- 功能最为强大,特别是在与系统交互中,几乎所有功能都能实现.
原生开发痛点
-
实时性限制&&新功能依赖升级
- 一些实时性或者紧急需求必须通过App直接发版来解决问题,发布周期长,应用市场审核很浪费时间,而且用户升级率不高;
- 当产品策划提到一些新功能场景时,都必须通过一个完整的迭代流程来进行开发,最终通过发布新版本来让用户使用到新的功能,开发和测试周期长。同时,用户如果想使用新功能,必须依赖升级。无法让旧版本的用户使用到新功能。
-
Bug无法热修复
- 移动开发过程中经常会出现因为考虑不周导致的一些线上逻辑问题或者崩溃问题,一般情况下都会通过重新打包发布应用市场来解决,目前也有更方便的通过补丁来解决问题。通过动态化方案也可以更好的通过热发的方式来修复bug。简单高效。
- App Store 2017年3月要求开发者移除热更新代码。2018年11月27日拼多多,搜狗导航,荔枝FM等被下架
-
多端协作成本高,不能跨平台
- 目前整个移动市场是分为android和ios,当需求提出的时候,会同时通知到android和ios两位开发,进行需求评审和功能迭代,在需求沟通和实现过程中总会出现各种沟通问题导致需求实现效果不统一,同时两位开发也会很浪费人力。通过动态化方案,两端可以共用同一套代码,来解决各自的逻辑,能够节省很多人力。
Android 系统架构
Google官方提供的经典分层架构图,从下往上依次分为Linux内核、HAL、系统Native库和Android运行时环境、Java框架层以及应用层这5层架构,其中每一层都包含大量的子模块或子系统。
Linux内核层
Android系统建立在Linux 2.6之上,这一层为Android设备的各种硬件提供了底层的驱动(Linux内核提供了安全性、内存管理、进程管理、网络协议和驱动模型等核心系统服务)。
Linux内核也是系统硬件和软件叠层之间的抽象层。
硬件抽象层 (HAL)
硬件抽象层 (HAL) 提供标准接口,HAL包含多个库模块,其中每个模块都为特定类型的硬件组件实现一组接口,比如WIFI/蓝牙模块,当框架API请求访问设备硬件时,Android系统将为该硬件加载相应的库模块。
Android Runtime & 系统库
每个应用都在其自己的进程中运行,都有自己的虚拟机实例。ART通过执行DEX文件可在设备运行多个虚拟机,DEX文件是一种专为Android设计的字节码格式文件,经过优化,使用内存很少。ART主要功能包括:预先(AOT)和即时(JIT)编译,优化的垃圾回收(GC),以及调试相关的支持。 这里的Native系统库主要包括init孵化来的用户空间的守护进程、HAL层以及开机动画等。启动init进程(pid=1),是Linux系统的用户进程, init进程是所有用户进程的鼻祖。
Framework层
应用程序框架层提供开发Android应用程序所需的一系列类库,使开发人员可以进行快速的应用程序开发,方便重用组件,也可以通过继承实现个性化的扩展。
- 丰富而又可扩展的视图(Views),可以用来构建应用程序, 它包括列表(lists),网格(grids),文本框(text boxes),按钮(buttons), 甚至可嵌入的web浏览器;
- 内容提供器(Content Providers)使得应用程序可以访问另一个应用程序的数据(如联系人数据库),或者共享它们自己的数据;
- 资源管理器(Resource Manager)提供非代码资源的访问,如本地字符串,图形,和布局文件( layout files );
- 通知管理器 (Notification Manager) 使得应用程序可以在状态栏中显示自定义的提示信息;
- 活动管理器( Activity Manager) 用来管理应用程序生命周期并提供常用的导航回退功能。
App层
Android平台的应用层上包括各类与用户直接交互的应用程序,或由java语言编写的运行于后台的服务程序。例如,智能手机上实现的常见基本功能 程序,诸如SMS短信,电话拨号,图片浏览器,日历,游戏,地图,web浏览器等程序,以及开发人员开发的其他应用程序。
ios系统架构
iOS基于UNIX系统,iOS的系统架构分为四层,由上到下一次为:触摸层(Cocoa Touch layer)、媒体层(Media layer)、核心服务层(Core Services layer)、核心操作系统层(Core OS layer),如下图:
触摸层(Cocoa Touch layer)
为应用程序开发提供了各种常用的框架并且大部分框架与界面有关,本质上来说它负责用户在iOS设备上的触摸交互操作。如NotificationCenter的本地通知和远程推送服务,iAd广告框架,GameKit游戏工具框架,消息UI框架,图片UI框架,地图框架,连接手表框架,自动适配等等
媒体层(Media layer)
提供应用中视听方面的技术,如图形图像相关的CoreGraphics,CoreImage,GLKit,OpenGL ES,CoreText,ImageIO等等。声音技术相关的CoreAudio,OpenAL,AVFoundation,视频相关的CoreMedia,Media Player框架,音视频传输的AirPlay框架等等。
核心服务层(Core Services layer)
提供给应用所需要的基础的系统服务。如Accounts账户框架,广告框架,数据存储框架,网络连接框架,地理位置框架,运动框架等等。这些服务中的最核心的是CoreFoundation和Foundation框架,定义了所有应用使用的数据类型。CoreFoundation是基于C的一组接口,Foundation是对CoreFoundation的OC封装。
核心操作系统层(Core OS layer)
包含大多数低级别接近硬件的功能,它所包含的框架常常被其它框架所使用。Accelerate框架包含数字信号,线性代数,图像处理的接口。针对所有的iOS设备硬件之间的差异做优化,保证写一次代码在所有iOS设备上高效运行。CoreBluetooth框架利用蓝牙和外设交互,包括扫描连接蓝牙设备,保存连接状态,断开连接,获取外设的数据或者给外设传输数据等等。Security框架提供管理证书,公钥和私钥信任策略,keychain,hash认证数字签名等等与安全相关的解决方案。
跨平台开发
跨平台开发的目的
- write once,run everywhere
- 线上动态性,不需要频繁更新版本即可实现新业务的上线
- 增加代码复用,减少开发者对多个平台差异适配的工作量,解决多端不一致的问题
- 提高业务专注的同时,提供比web更好的体验
- 降低开发成本
跨平台开发流派
- Web 流:也被称为 Hybrid 技术,它基于 Web 相关技术来实现界面及功能:
小程序,快应用
- 代码转换流:使用相同的开发语言来开发, 然后转成不同平台下能运行的语言:
Flutter Web(Dart2Js)
- 编译流:将某个语言编译为二进制文件,生成动态库或打包成 apk/ipa/xap 文件:
Xamarin(iOS 下是以 AOT 的方式编译为二进制文件的, 已于 2024 年 5 月 1 日停止支持。)
- 虚拟机流:通过将某个语言的虚拟机移植到不同平台上来运行:
Flutter,React Native
跨平台开发主流技术
- Flutter(Google)
- ReactNative(FaceBook), Weex(Alibaba)
- Hybrid App
- 小程序
比较:
Flutter
闲鱼、美团,饿了么、NOW直播(腾讯)、京东金融
Flutter是谷歌的最新移动UI框架。Beta1版本于2018年2月27日在2018 世界移动大会公布,Beta2版本2018年3月6日发布。开发者可以使用 Flutter 在 iOS 和 Android 平台上开发原生应用。它也是未来的Google新操作系统 Fuchsia 应用的主要开发方式。
Flutter是一种新型的“客户端”技术。它的最终目标是替代包含几乎所有平台的开发:iOS,Android,Web,桌面;做到了一次编写,多处运行。
Google 出品,Dart语言,Flutter Engine引擎,响应式设计模式,原生渲染
-
优点:
- 热重载(Hot Reload),利用Android Studio直接一个ctrl+s就可以保存并重载,模拟器立马就可以看见效果,相比原生冗长的编译过程强很多;
- 一切皆为Widget的理念,对于Flutter来说,手机应用里的所有东西都是Widget,通过可组合的空间集合、丰富的动画库以及分层课扩展的架构实现了富有感染力的灵活界面设计;
- 借助可移植的GPU加速的渲染引擎以及高性能本地代码运行时以达到跨平台设备的高质量用户体验。 简单来说就是:最终结果就是利用Flutter构建的应用在运行效率上会和原生应用差不多。
-
缺点:
- 不支持热更新;
- 三方库很少,需要自己造轮子;
- 适配问题:随着操作系统和Flutter框架的不断更新,开发者可能需要修改大量的代码以适应新的版本和特性
- 代码可读性较差:Flutter的代码可读性相对较差,特别是对于不熟悉Dart语言和Flutter框架的开发者来说,可能需要花费更多的时间来理解和维护代码。
- 打包后文件较大:由于Flutter应用包含了自己的渲染引擎和框架代码,因此打包后的应用文件相对较大,可能会影响应用的下载和安装速度。
-
理念架构:
Flutter 架构主要分为 Framework 和 Engine,我们基于 Framework 开发App,运行在 Engine 上。Engine 是 Flutter 的独立虚拟机,由它适配和提供跨平台支持,目前猜测 Flutter 应用程序在 Android 上,是直接运行 Engine 上 所以在是不需要Dalvik虚拟机。
得益于 Engine 层,Flutter 甚至不使用移动平台的原生控件, 而是使用自己 Engine 来绘制 Widget (Flutter的显示单元),而 Dart 代码都是通过 AOT 编译为平台的原生代码,所以 Flutter 可以 直接与平台通信,不需要JS引擎的桥接。同时 Flutter 唯一要求系统提供的是 canvas,以实现UI的绘制。
- FrameWork层
Flutter的顶层是用drat编写的框架(SDK),它实现了一套基础库,包含Material(Android风格UI)和Cupertino(iOS风格)的UI界面,下面是通用的Widgets(组件),之后是一些动画、绘制、渲染、手势库等。这个纯 Dart实现的 SDK被封装为了一个叫作 dart:ui的 Dart库。我们在使用 Flutter写 App的时候,直接导入这个库即可使用组件等功能。
- Engine层
第一Skia是Google的一个 2D的绘图引擎库,其前身是一个向量绘图软件,Chrome和 Android均采用 Skia作为绘图引擎。Skia提供了非常友好的 API,并且在图形转换、文字渲染、位图渲染方面都提供了友好、高效的表现。Skia是跨平台的,所以可以被嵌入到 Flutter的 iOS SDK中,而不用去研究 iOS闭源的 Core Graphics / Core Animation。Android自带了 Skia,所以 Flutter Android SDK要比 iOS SDK小很多。
第二 Dart 运行时环境
第三 文本渲染布局引擎。
- Flutter for Web
Dart能够使用Dart2Js编译器把Dart代码编译成Js代码。大多数原生App元素能够通过DOM实现,DOM实现不了的元素可以通过Canvas来实现。
React Native
墨刀,京东,手机百度 ,腾讯QQ,QQ空间,Facebook及旗下应用
React Native (简称RN)是Facebook于2015年4月开源的跨平台移动应用开发框架,目前支持iOS和安卓两大平台。RN使用Javascript语言,类似于HTML的JSX,以及CSS来开发移动应用,因此熟悉Web前端开发的技术人员只需很少的学习就可以进入移动应用开发领域。React Native着力于提高多平台开发的开发效率 —— 仅需学习一次,编写任何平台
Facebook 出品,JavaScript语言,JSCore引擎,React设计模式,原生渲染
-
优点:
- 效率体验接近原生应用质量,发布和开发成本低于原生App;
- 支持热更新,快速迭代;
- 社区活跃,基本坑点都能解决;
- 代码跨越双平台
-
缺点:
- RN 的开源库质量参差不齐;
- RN 运行时的初始化太慢,首次渲染时间慢(需要从 主线程 -> JS -> Yoga -> 主线程);
- 调试困难,JSCore 在 iOS / Android 上不一致 (Android 上是 RN 自己 bundle 的),很难 debug 这种坑
-
理念架构
react native 用了 react 的设计模式,但UI渲染、动画效果、网络请求等均由原生端实现。开发者编写的js代码,通过 react native 的中间层转化为原生控件和操作。 如下图所示,react native 的跨平台是实现主要由三层构成,其中 C++ 实现的动态连结库(.so),作为中间适配层桥接,实现了js端与原生端的双向通信交互。这里最主要是封装了 JavaScriptCore 执行js的解析,而 react native 运行在JavaScriptCore中,所以不存在浏览器兼容的问题。其中在IOS上直接使用内置的javascriptcore,在Android 则使用webkit.org官方开源的jsc.so。
- 实现原理
和前端开发不同,react native 所有的标签都不是真实控件,JS代码中所写控件的作用,类似 Map 中的 key 值。JS端通过这个 key 组合的 Dom ,最后Native端会解析这个 Dom ,得到对应的Native控件渲染,如 Android 中 标签对应 ViewGroup 控件。
在 react native 中,JS端是运行在独立的线程中(称为JS Thread )。JS Thread 作为单线程逻辑,不可能处理耗时的操作。那么如 fetch 、图片加载 、 数据持久化 等操作,在 Android 中实际对应的是 okhttp 、Fresco 、SharedPreferences等。而跨线程通信,也意味着 Js Thread 和原生之间交互与通讯是异步的。
可以看出,跨平台的关键在于C++层,开发人员大部分时候,只专注于JS 端的代码实现。 在原生端提供的各种 Native Module 模块(如网络请求,ViewGroup控件),和 JS 端提供的各种 JS Module(如JS EventEmiter模块),都会在C++实现的so中保存起来,双方的通讯通过C++中的保存的映射,最终实现两端的交互。
Hybrid App(Android/iOS+Html5)
微信,爱奇艺
Hybrid App主要以JS+Native两者相互调用为主,从开发层面实现“一次开发,多处运行”的机制,成为真正适合跨平台的开发。Hybrid App兼具了Native App良好用户体验的优势,也兼具了Web App使用HTML5跨平台开发低成本的优势。
基于WebView UI, 原生渲染
-
优点
- 兼具了Native App良好用户体验的优势;
- 提升了开发效率,h5可以多平台复用,由服务器快速迭代;
- 实现简单,且原生与h5开发人员充沛。
-
缺点
- 体验比不上原生,webView性能差;
- 适用部分展示页面,复杂交互仍需要原生开发;
- 需要对应平台人员配合,jsApi因需求需要调整,版本迭代并不自由.
-
理念架构 作为一种混合开发的模式,Hybrid APP底层依赖于Native提供的容器(UIWebview),上层使用Html&Css&JS做业务开发,底层透明化、上层多多样化,这种场景非常有利于前端介入,非常适合业务快速迭代。
- 技术原理
Hybrid App的本质,其实是在原生的 App 中,使用 WebView 作为容器直接承载 Web页面。因此,最核心的点就是 Native端 与 H5端 之间的双向通讯层,其实这里也可以理解为我们需要一套跨语言通讯方案,来完成 Native(Java/Objective-c/...) 与 JavaScript 的通讯。这个方案就是我们所说的 JSBridge,而实现的关键,便是作为容器的 WebView,一切的原理都是基于 WebView 的机制。
-
App中H5的接入方式
- 在线H5,这是最常见的一种方式。
只需要将H5代码部署到服务器上,只要把对应的 URL地址 给到客户端,用 WebView 打开该URL,即可嵌入。 该方式的好处在于:
- 独立性强,有非常独立的开发/调试/更新/上线能力;
- 资源放在服务器上,完全不会影响客户端的包体积;
- 接入成本很低,完全的热更新机制。
- 但相对的,这种方式也有对应的缺点:
- 完全的网络依赖,在离线的情况下无法打开页面;
- 首屏加载速度依赖于网络,网络较慢时,首屏加载也较慢;
通常,这种方式更适用在一些比较轻量级的页面上,例如一些帮助页、提示页、使用攻略等页面。这些页面的特点是功能性不强,不太需要复杂的功能协议,且不需要离线使用。在一些第三方页面接入上,也会使用这种方式,例如我们的页面调用微信JS-SDK。
-
内置包H5,这是一种本地化的嵌入方式,我们需要将代码进行打包后下发到客户端,并由客户端直接解压到本地储存中。通常我们运用在一些比较大和比较重要的模块上。其优点是:
-
由于其本地化,首屏加载速度快,用户体验更为接近原生;
-
可以不依赖网络,离线运行;
-
但同时,它的劣势也十分明显:
-
开发流程/更新机制复杂化,需要客户端,甚至服务端的共同协作;
-
会相应的增加 App 包体积;
这两种接入方式均有自己的优缺点,应该根据不同场景进行选择。
小程序
小程序开发本质上还是前端 HTML + CSS + JS 那一套逻辑,它基于 WebView 和微信自己定义的 一套 JS/WXML/WXSS/JSON 来开发和渲染页面。
uni-app(DCloud)
uni-app 是一个使用 Vue.js 开发跨平台应用的前端框架,开发者编写一套代码,可编译到iOS、Android、H5、小程序等多个平台。
案例
- Flutter
- React Native
- Hybrid App