原生开发与跨平台技术
1.1 原生开发
原生应用程序是指某一个移动平台(比如iOS或安卓)所特有的应用,使用相应平台支持的开发工具和语言,并直接调用系统提供的SDK API。比如Android原生应用就是指使用Java或Kotlin语言直接调用Android SDK开发的应用程序;而iOS原生应用就是指通过Objective-C或Swift语言直接调用iOS SDK开发的应用程序。原生开发有以下主要优势:
- 可访问平台全部功能(GPS、摄像头);
- 速度快、性能高、可以实现复杂动画及绘制,整体用户体验好;
主要缺点:
- 平台特定,开发成本高;不同平台必须维护不同代码,人力成本随之变大;
- 内容固定,动态化弱,大多数情况下,有新功能更新时只能发版;
1.2 跨平台技术
针对原生开发面临问题,人们一直都在努力寻找好的解决方案,而时至今日,已经有很多跨平台框架(注意,本书中所指的“跨平台”若无特殊说明,即特指Android和iOS两个平台),根据其原理,主要分为三类:
- H5+原生(Cordova、Ionic、微信小程序)
- JavaScript开发+原生渲染 (React Native、Weex、快应用)
- 自绘UI+原生(QT for mobile、Flutter)
h5 + 原生混合开发
通过原生的网页加载控件WebView来加载 h5 内容,而WebView实质上就是一个浏览器内核,其JavaScript依然运行在一个权限受限的沙箱中,所以对于大多数系统能力都没有访问权限,如无法访问文件系统等。所以需要客户端实现一个访问系统能力的 API 供 h5 调用。也就是bridge。
React Native
React Native 是 React 在原生移动应用平台的衍生产物,主要的区别在于虚拟DOM映射的对象是什么。React中虚拟DOM最终会映射为浏览器DOM树,而RN中虚拟DOM会通过 JavaScriptCore 映射为原生控件树。
JavaScriptCore 是一个JavaScript解释器,它在React Native中主要有两个作用:
- 为JavaScript提供运行环境。
- 是JavaScript与原生应用之间通信的桥梁,作用和JsBridge一样,事实上,在iOS中,很多JsBridge的实现都是基于 JavaScriptCore 。
而RN中将虚拟DOM映射为原生控件的过程中分两步:
- 布局消息传递; 将虚拟DOM布局信息传递给原生;
- 原生根据布局信息通过对应的原生控件渲染控件树;
至此,React Native 便实现了跨平台。 相对于混合应用,由于React Native是原生控件渲染,所以性能会比混合应用中H5好很多,同时React Native使用了Web开发技术栈,也只需维护一份代码,同样是跨平台框架。
Weex
Weex是阿里巴巴于2016年发布的跨平台移动端开发框架,思想及原理和React Native类似,最大的不同是语法层面,Weex支持Vue语法和Rax语法,Rax 的 DSL(Domain Specific Language) 语法是基于 React JSX 语法而创造。与 React 不同,在 Rax 中 JSX 是必选的,它不支持通过其它方式创建组件,所以学习 JSX 是使用 Rax 的必要基础。而React Native只支持JSX语法。
flutter简介
Flutter 是 Google推出并开源的移动应用开发框架,主打跨平台、高保真、高性能。开发者可以通过 Dart语言开发 App,一套代码同时运行在 iOS 和 Android平台。
1.1跨平台自绘引擎
Flutter既不使用WebView,也不使用操作系统的原生控件。 相反,Flutter使用自己的高性能渲染引擎来绘制widget。这样不仅可以保证在Android和iOS上UI的一致性,而且也可以避免对原生控件依赖而带来的限制及高昂的维护成本。
1.2高性能
Flutter高性能主要靠两点来保证
Flutter APP采用Dart语言开发。Dart在 JIT(即时编译)模式下,速度与 JavaScript基本持平。但是 Dart支持 AOT,当以 AOT模式运行时,JavaScript便远远追不上了。
Flutter使用自己的渲染引擎来绘制UI,布局数据等由Dart语言直接控制,所以在布局过程中不需要像RN那样要在JavaScript和Native之间通信,这在一些滑动和拖动的场景下具有明显优势,因为在滑动和拖动过程往往都会引起布局发生变化,所以JavaScript需要和Native之间不停的同步布局信息,这和在浏览器中要JavaScript频繁操作DOM所带来的问题是相同的,都会带来比较可观的性能开销
1.3为什么使用Dart
开发效率
- 基于JIT的快速开发周期:Flutter在开发阶段采用,采用JIT模式,这样就避免了每次改动都要进行编译,极大的节省了开发时间;
- 基于AOT的发布包: Flutter在发布时可以通过AOT生成高效的ARM代码以保证应用性能。而JavaScript则不具有这个能力。
高性能
- Flutter旨在提供流畅、高保真的的UI体验。为了实现这一点,Flutter中需要能够在每个动画帧中运行大量的代码。这意味着需要一种既能提供高性能的语言,而不会出现会丢帧的周期性暂停,而Dart支持AOT,在这一点上可以做的比JavaScript更好。
- 类型安全
- 由于Dart是类型安全的语言,支持静态类型检测,所以可以在编译前发现一些类型的错误,并排除潜在问题。
- 团队支持程度
1.4flutter框架结构
Flutter Framework
这是一个纯 Dart实现的 SDK,它实现了一套基础库,自底向上,我们来简单介绍一下:
- 底下两层(Foundation和Animation、Painting、Gestures)在Google的一些视频中被合并为一个dart UI层,对应的是Flutter中的
dart:ui
包,它是Flutter引擎暴露的底层UI库,提供动画、手势及绘制能力。 - Rendering层,这一层是一个抽象的布局层,它依赖于dart UI层,Rendering层会构建一个UI树,当UI树有变化时,会计算出有变化的部分,然后更新UI树,最终将UI树绘制到屏幕上,这个过程类似于React中的虚拟DOM。Rendering层可以说是Flutter UI框架最核心的部分,它除了确定每个UI元素的位置、大小之外还要进行坐标变换、绘制(调用底层dart:ui)。
- Widgets层是Flutter提供的的一套基础组件库,在基础组件库之上,Flutter还提供了 Material 和Cupertino两种视觉风格的组件库。而我们Flutter开发的大多数场景,只是和这两层打交道。
参考资料
https://book.flutterchina.club/chapter1/mobile_development_intro.html