原生革命--跨平台开发技术解析

4,501 阅读36分钟

这篇文章,我将着重分析当前主流跨平台开发解决方案(偏架构)如Flutter、RN、Weex、Hybrid App,并对新晋跨端解决方案Fusion和Chameleon做一些分析,在传统原生开发不断被唱衰、大前端试图一统天下的今天,了解这些知识是有必要的.


目录

1.原生开发,优势与痛点分析
2.Android系统架构
3. iOS系统架构
4.跨平台开发的目的&&主流技术
5.移动端主流跨平台技术介绍
5.1 Flutter
5.2 ReactNative
5.3 Weex
5.4 Hybrid App
5.5 小程序&&快应用
6.横跨APP、小程序、web端的技术
6.1 Chameleon
6.2 uni-app
7.阿里中后台UI解决方案 - Fusion
8. 案例分析与拓展导读

原生开发

Native App是一种基于智能手机本地操作系统如iOS、Android、WP并使用原生程式编写运行的第三方应用程序,也叫本地app。一般使用的开发语言为Java、C++、Objective-C。 自iOS和Android这两个的手机操作系统发布以来,在互联网界从此就多了一个新的名词:App意为运行在智能的移动终端设备第三方应用程序)。 Native App因为位于平台层上方,向下访问和兼容的能力会比较好一些,可以支持在线或离线,消息推送或本地资源访问,摄像拨号功能的调取。

优势

  • 1、相比于其它模式,提供最佳的用户体验,最优质的用户界面,最华丽的交互;
  • 2、针对不同平台提供不同体验;
  • 3、可节省带宽成本,打开速度更快;
  • 4、功能最为强大,特别是在与系统交互中,几乎所有功能都能实现.

原生开发痛点

  • 实时性限制&&新功能依赖升级

    • 一些实时性或者紧急需求必须通过App直接发版来解决问题,发布周期长,应用市场审核很浪费时间,而且用户升级率不高;
    • 当产品策划提到一些新功能场景时,都必须通过一个完整的迭代流程来进行开发,最终通过发布新版本来让用户使用到新的功能,开发和测试周期长。同时,用户如果想使用新功能,必须依赖升级。无法让旧版本的用户使用到新功能。
  • Bug无法热修复

    • 移动开发过程中经常会出现因为考虑不周导致的一些线上逻辑问题或者崩溃问题,一般情况下都会通过重新打包发布应用市场来解决,目前也有更方便的通过补丁来解决问题。通过动态化方案也可以更好的通过热发的方式来修复bug。简单高效。
    • App Store 2017年3月要求开发者移除热更新代码,2017年6月下架大量应用 2018年11月27日拼多多,搜狗导航,荔枝FM等被下架
  • 多端协作成本高,不能跨平台

    • 目前整个移动市场是分为android和ios,当需求提出的时候,会同时通知到android和ios两位开发,进行需求评审和功能迭代,在需求沟通和实现过程中总会出现各种沟通问题导致需求实现效果不统一,同时两位开发也会很浪费人力。通过动态化方案,两端可以共用同一套代码,来解决各自的逻辑,能够节省很多人力。

Android 系统架构

为了能让大家整体上大致了解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浏览器等程序,以及开发人员开发的其他应用程序。

JNI

Java层与Native(C/C++)层之间的纽带


ios系统架构

iOS基于UNIX系统,iOS的系统架构分为四层,由上到下一次为:可触摸层(Cocoa Touch layer)、媒体层(Media layer)、核心服务层(Core Services layer)、核心操作系统层(Core OS layer),如下图:

note.youdao.com/yws/public/…

触摸层

为应用程序开发提供了各种常用的框架并且大部分框架与界面有关,本质上来说它负责用户在iOS设备上的触摸交互操作。如NotificationCenter的本地通知和远程推送服务,iAd广告框架,GameKit游戏工具框架,消息UI框架,图片UI框架,地图框架,连接手表框架,自动适配等等

媒体层

提供应用中视听方面的技术,如图形图像相关的CoreGraphics,CoreImage,GLKit,OpenGL ES,CoreText,ImageIO等等。声音技术相关的CoreAudio,OpenAL,AVFoundation,视频相关的CoreMedia,Media Player框架,音视频传输的AirPlay框架等等。

核心服务层

提供给应用所需要的基础的系统服务。如Accounts账户框架,广告框架,数据存储框架,网络连接框架,地理位置框架,运动框架等等。这些服务中的最核心的是CoreFoundation和Foundation框架,定义了所有应用使用的数据类型。CoreFoundation是基于C的一组接口,Foundation是对CoreFoundation的OC封装。

核心操作系统层包括

包含大多数低级别接近硬件的功能,它所包含的框架常常被其它框架所使用。Accelerate框架包含数字信号,线性代数,图像处理的接口。针对所有的iOS设备硬件之间的差异做优化,保证写一次代码在所有iOS设备上高效运行。CoreBluetooth框架利用蓝牙和外设交互,包括扫描连接蓝牙设备,保存连接状态,断开连接,获取外设的数据或者给外设传输数据等等。Security框架提供管理证书,公钥和私钥信任策略,keychain,hash认证数字签名等等与安全相关的解决方案。


跨平台开发

跨平台开发的目的

  • write once,run everywhere
  • 线上动态性,不需要频繁更新版本即可实现新业务的上线
  • 增加代码复用,减少开发者对多个平台差异适配的工作量,解决多端不一致的问题
  • 提高业务专注的同时,提供比web更好的体验
  • 降低开发成本

跨平台开发流派

  • Web 流:也被称为 Hybrid 技术,它基于 Web 相关技术来实现界面及功能
    Cordova,AppCan,小程序,快应用

  • 代码转换流:将某个语言转成 Objective-C、Java 或 C#,java2OC,OC2Java,java2C#,Dart2Js,然后使用不同平台下的官方工具来开发
    Flutter Web(Dart2Js)

  • 编译流:将某个语言编译为二进制文件,生成动态库或打包成 apk/ipa/xap 文件
    Xamarin(iOS 下是以 AOT 的方式编译为二进制文件的)

  • 虚拟机流:通过将某个语言的虚拟机移植到不同平台上来运行
    Flutter,Titanium,React Native,Weex

百度吴多益2015年准确预测了RN成为跨平台开发主流技术
数据-2017年三月跨平台App分布

跨平台开发主流技术

  • Flutter(Google)
  • ReactNative(FaceBook)
  • Weex(Alibaba)
  • Hybrid App
  • Cordova(原PhoneGap,Adobe)
  • 小程序,快应用

比较

解决方案 ReactNative Weex Flutter Hybrid App
平台实现 JavaScript JavaScript 无桥接,原生编码 无桥接,原生编码
引擎 JSCore JS V8 Flutter engine 原生渲染
核心语言 React Vue Dart Java/Obeject-C
上手难度(原生角度) 较高 一般 一般 容易
框架程度 较重 较轻 -
特点 适合开发整体App 适合单页面 适合开发整体App 适合开发整体App
社区 丰富,FaceBook重点维护 有点残念,托管apache 刚出道小鲜肉,拥护者众多 丰富
线上动态性
跨平台支持 Android、iOS Android、iOS、Web Android、iOS Android、iOS

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构建的应用在运行效率上会和原生应用差不多。

缺点

  • 不支持热更新;
  • 三方库很少,需要自己造轮子;
  • dart语言编写,掌握该语言的开发者很少。

理念架构

Flutter 主要分为 Framework 和 Engine,我们基于Framework 开发App,运行在 Engine 上。Engine 是 Flutter 的独立虚拟机,由它适配和提供跨平台支持,目前猜测 Flutter 应用程序在 Android 上,是直接运行 Engine 上 所以在是不需要Dalvik虚拟机。(这是比kotlin更彻底,抛弃JVM的纠缠? )
  得益于 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分层.png

绘图基本原理

提到原理,我们要从屏幕显示图像的基本原理开始谈起。 我们都知道显示器以固定的频率刷新,比如 iPhone的 60Hz、iPad Pro的 120Hz。当一帧图像绘制完毕后准备绘制下一帧时,显示器会发出一个垂直同步信号(VSync),所以 60Hz的屏幕就会一秒内发出 60次这样的信号。 并且一般地来说,计算机系统中,CPU、GPU和显示器以一种特定的方式协作:CPU将计算好的显示内容提交给 GPU,GPU渲染后放入帧缓冲区,然后视频控制器按照 VSync信号从帧缓冲区取帧数据传递给显示器显示。

所以,Android、iOS的 App在显示 UI时是如此,Flutter也不例外,也遵循了这种模式。所以从这里可以看出 Flutter和 React-Native之众的本质区别:React-Native之类只是扩展调用 OEM组件,而 Flutter是自己渲染。

Flutter绘制流程

Flutter只关心向 GPU提供视图数据,GPU的 VSync信号同步到 UI线程,UI线程使用 Dart来构建抽象的视图结构,这份数据结构在 GPU线程进行图层合成,视图数据提供给 Skia引擎渲染为 GPU数据,这些数据通过 OpenGL或者 Vulkan提供给 GPU。

所以 Flutter并不关心显示器、视频控制器以及 GPU具体工作,它只关心 GPU发出的 VSync信号,尽可能快地在两个 VSync信号之间计算并合成视图数据,并且把数据提供给 GPU。

Flutter两层.png

Flutter for Web

在前些日子举办的Google IO 2019 年度开发者大会上,Flutter web作为一个很亮眼的技术受到了开发者的追捧。这是继Flutter支持Android、IOS等设备之后,又一个里程碑式的版本,后续还会支持windows、linux、Macos、chroms等其他嵌入式设备。

通过对比,可以发现,web框架层和mobile的几乎一模一样。因此只需要重新实现一下引擎和嵌入层,不用变动Flutter API就可以完全可以将UI代码从Android / IOS Flutter App移植到Web。Dart能够使用Dart2Js编译器把Dart代码编译成Js代码。大多数原生App元素能够通过DOM实现,DOM实现不了的元素可以通过Canvas来实现。

成熟案例

闲鱼 - Release Flutter的最后一公里


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 这种坑

理念架构

“Learn once, write anywhere” ,代表着 Facebook对 react native 的定义:学习 react ,同时掌握 web 与 app 两种开发技能。 react native 用了 react 的设计模式,但UI渲染、动画效果、网络请求等均由原生端实现。开发者编写的js代码,通过 react native 的中间层转化为原生控件和操作,比ionic等跨平台应用,大大提高了的用户体验。
  总结起来其实就是利用 JS 来调用 Native 端的组件,从而实现相应的功能。
  如下图所示,react native 的跨平台是实现主要由三层构成,其中 C++ 实现的动态连结库(.so),作为中间适配层桥接,实现了js端与原生端的双向通信交互。这里最主要是封装了 JavaScriptCore 执行js的解析,而 react native 运行在JavaScriptCore中,所以不存在浏览器兼容的问题。
  其中在IOS上直接使用内置的javascriptcore,在Android 则使用webkit.org官方开源的jsc.so。

ReactNative理念架构.png

实现原理

和前端开发不同,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++中的保存的映射,最终实现两端的交互。

ReactNative原理.png

  
ReactNative三层.png

Virtual Dom

虚拟DOM是一种使用js对象来描述真实DOM的技术,主要是运用一种diff的算法,高效完成局部数据刷新。网页实际上都是解析成dom的格式被加载渲染,但是每次渲染都是dom数据的重载,而virtual dom则是实现了部分重新加载这样就大大提高了高效性。   通过这种技术,一方面我们能精确知道哪些真实DOM改变了,从而尽量减少DOM操作的性能开销。另外一方面由于真实DOM都通过js对象来描述了,所以我们可以尝试使用数据来驱动DOM开发,比如著名的react就是这样做的。

//virtual dom
 {
    tag: 'div'
    data: {
        class: 'outer'
    },
    children: [
        {
            tag: 'div',
            data: {
                class: 'inner'
            }
            text: 'Virtual DOM'
        }
    ]
}

// 真实 dom
<div class="outer">
    <span class="inner">Virtual DOM</span>
</div>

//Js代码 Text被编译成Android的TextView
render() { 
        return (<View > 
                <Text >Hello,World</Text>
         </View>); 
}

成熟案例

京东618:ReactNative框架在京东无线端的实践


WEEX

淘宝,天猫,支付宝,网易考拉,网易严选

2016年4月21日,阿里巴巴在Qcon大会上宣布跨平台移动开发工具Weex。Weex框架能够完美兼顾性能与动态性,让移动开发者通过简捷的前端语法写出Native级别的性能体验,并支持iOS、安卓、YunOS及Web等多端部署。Weex基于开源的Vue.JS, 相比于 RN来说 入门简单,容易上手。目前 阿里系的很多产品 比如淘宝,支付宝和一些小公司app都在用WEEX。

Alibaba 出品,JavaScript语言,JS V8引擎,Vue设计模式,原生渲染

优点

  • 单页开发模式效率极高,热更新发包体积小,并且跨平台性更强

缺点

  • 社区没有RN活跃,功能尚不健全,暂不适合完全使用Weex开发App

理念架构

“Write once, run everywhere”, weex的定义就像是:写个 vue 前端,顺便帮你编译成性能还不错的 apk 和 ipa(当然,现实有时很骨感)。基于 Vue 设计模式,支持 web、android、ios 三端,原生端同样通过中间层转化,将控件和操作转化为原生逻辑来提高用户体验。
  在 weex 中,主要包括三大部分:JS Bridge、Render、Dom,分别对应WXBridgeManager、WXRenderManager、WXDomManager,三部分通过WXSDKManager统一管理。其中 JS Bridge 和 Dom 都运行在独立的 HandlerThread 中,而 Render 运行在 UI 线程。
  JS Bridge 主要用来和 JS 端实现进行双向通信,比如把 JS 端的 dom 结构传递给 Dom 线程。Dom 主要是用于负责 dom 的解析、映射、添加等等的操作,最后通知UI线程更新。而 Render 负责在UI线程中对 dom 实现渲染。
  如下图,是生成dom,dom的解析,映射,添加,渲染的流程。   


  如上可知,因为JS端运行于独立的单线程中,所以为了保证运行的流畅性,一般需要避免在JS端执行耗时操作,比如:网络请求,图片加载等,其实都是在原生端完成,js端执行的是发起一个请求和响应一个结果。同时因为原生端与JS端是通过JS Bridge通讯,所以也需要尽量避免大数据和频繁的通讯,导致响应的延迟。
  原生端的dom的加载解析映射,也是性能的一大瓶颈。一般而言,Weex在Web端生成的,是通过webpack的webConfig打包成单页面的index.web.js文件;而在原生端,一般会通过webpack的weexEntry配置成多页面形式:即每一个需要独立的.vue的页面,最终会被打包成一个.js文件。所以打开每个页面时加载对应的js文件,这很好的减小了需要加载的文件大小,提高了dom的解析效率。最后,Weex默认打的js只包含业务js代码,基础js库已经被包含在weex sdk中,也使得体积会小很多。

实现原理

和 react native一样,weex 所有的标签也不是真实控件,JS 代码中所生成存的 dom,最后都是由 Native 端解析,再得到对应的Native控件渲染,如 Android 中 标签对应 WXTextView 控件。
  weex 中文件默认为 .vue ,而 vue 文件是被无法直接运行的,所以 vue 会被编译成 .js 格式的文件,Weex SDK会负责加载渲染这个js文件。Weex可以做到跨三端的原理在于:在开发过程中,代码模式、编译过程、模板组件、数据绑定、生命周期等上层语法是一致的。不同的是在 JS Framework 层的最后,web 平台和 Native 平台,对 Virtual DOM 执行的解析方法是有区别的。

实际上,在 Native 中对 bundle 文件的加载大致经历以下阶段:

  • weex 接收到 js 文件以后,JS Framework 根据文件为 Vue 模式,会调用weex-vue-framework 中提供的 createInstance方法创建实例。(也可能是Rax模式)
  • createInstance 中会执行 Js Entry 代码里 new Vue() 创建一个组件,通过其 render 函数创建出 Virtual DOM 节点。
  • 由JS V8 引擎上解析 Virtual DOM ,得到 Json 数据发送至 Dom 线,这里输出 Json 也是方便跨端的数据传输。
  • Dom 线程解析 Json 数据,得到对应的 WxDomObject,然后创建对应的WxComponent 提交 Render 。
  • Render在原生端最终处理处理渲染任务,并回调里JS方法。

weex工作流.jpg

得益于上层的统一性,只是通过 weex-vue-framework 判断是由Vue.js 生成真实的 Dom ,还是通过 Native Api 渲染组件,weex 一定程度上上,用JS 实现了 vue 一统天下的效果。    weex 在原生渲染 Render 时,在接收到渲染指令后,会逐步将数据渲染成原生组件。Render 通过解析渲染数据的描述,然后分发给不同的模块。
   比如 控件渲染属于 dom 模块中,页面跳转属于navigator模块等。模块的渲染过程并非一个执行完,再执行另一个的流程,而是类似流式的过程。如上一个  的组件还没渲染好,下一个'div'的渲染又发了过来。这样当一个组件的嵌套组件很多时,或者可以看到这个大组件内的UI,一个一个渲染出来的过程。
  weex 比起react native,主要是在JS V8的引擎上,多了 JS Framework 承当了重要的职责,使得上层具备统一性,可以支持跨三个平台。总的来说它主要负责是:管理Weex的生命周期;解析JS Bundle,转为Virtual DOM,再通过所在平台不同的API方法,构建页面;进行双向的数据交互和响应。      

weexJSV8.jpg

成熟案例

Weex在内涵段子发现页中的工程实践


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.jpg

技术原理

Hybrid App的本质,其实是在原生的 App 中,使用 WebView 作为容器直接承载 Web页面。因此,最核心的点就是 Native端 与 H5端 之间的双向通讯层,其实这里也可以理解为我们需要一套跨语言通讯方案,来完成 Native(Java/Objective-c/...) 与 JavaScript 的通讯。这个方案就是我们所说的 JSBridge,而实现的关键,便是作为容器的 WebView,一切的原理都是基于 WebView 的机制。

Hybrid技术原理.jpg

App中H5的接入方式

  • 在线H5,这是最常见的一种方式。
    我们只需要将H5代码部署到服务器上,只要把对应的 URL地址 给到客户端,用 WebView 打开该URL,即可嵌入。
    该方式的好处在于:

    • 独立性强,有非常独立的开发/调试/更新/上线能力;
    • 资源放在服务器上,完全不会影响客户端的包体积;
    • 接入成本很低,完全的热更新机制。
      但相对的,这种方式也有对应的缺点:
    • 完全的网络依赖,在离线的情况下无法打开页面;
    • 首屏加载速度依赖于网络,网络较慢时,首屏加载也较慢;

通常,这种方式更适用在一些比较轻量级的页面上,例如一些帮助页、提示页、使用攻略等页面。这些页面的特点是功能性不强,不太需要复杂的功能协议,且不需要离线使用。在一些第三方页面接入上,也会使用这种方式,例如我们的页面调用微信JS-SDK。

  • 内置包H5,这是一种本地化的嵌入方式,我们需要将代码进行打包后下发到客户端,并由客户端直接解压到本地储存中。通常我们运用在一些比较大和比较重要的模块上。其优点是:
    • 由于其本地化,首屏加载速度快,用户体验更为接近原生;
    • 可以不依赖网络,离线运行;
      但同时,它的劣势也十分明显:
    • 开发流程/更新机制复杂化,需要客户端,甚至服务端的共同协作;
    • 会相应的增加 App 包体积;

这两种接入方式均有自己的优缺点,应该根据不同场景进行选择。

成熟案例

阅文 - 起点海外版 Hybrid App-内嵌页优化实践

Hybrid 开发框架

Cordova

Apache Cordova是一个开源移动开发框架。它允许您使用标准Web技术 - HTML5,CSS3和JavaScript进行跨平台开发。如 Android 和 iOS 。尽管你在开发中仍然需要用到该平台特定的技术,例如 Android SDK 或 Xcode ,你也无需再编写任何 Android 或 iOS 代码就能完成应用开发。 Cordova 能够将你的 HTML/JS 代码打包在一个原生的容器中运行,并依赖符合标准的API绑定来访问每个设备的功能,如传感器,数据,网络状态等。 基本功能完全具备,对于底层,如摄像头之类的,需要插件。

优点

  • 写一次代码,多个平台都适用(iOS,Android,Blackberry,Symbian,WP等)。
  • 基本功能完全具备,对于底层,如摄像头之类的,需要插件。

缺点

  • 运行速度相对较慢
  • Web开发者需掌握部分原生开发知识,增加学习成本

架构

用 Cordova 和 Vue.js 构建一个 APP

1.安装Cordova CLI(cordova命令行界面)
2.创建应用程序
3.添加平台
4.添加插件(让应用具备访问设备级功能)
5.使用合并自定义每个平台
6.更新Cordova和项目
7.打包

Hybrid 其他框架

AppCan

AppCan是基于HTML5技术的Hybird跨平台移动应用开发工具。开发者利用 Html5+Css3+JavaScript技术,通过AppCan IDE集成开发系统、云端打包器等,快速开发 出Android、iOS、WP平台上的移动应用。

Titanium

Titanium移动平台是所有移动开发平台中比较另类的,它将JavaScript和本地库链接在一起, 编译成字节码,针对iOS以及Android两个平台分别构建一个软件包。应用程序使用HTML, JavaScript和CSS进行开发,并支持PHP,Ruby和Python。应用程序可以使用 Appcelerator API 访问本地特性。并提供Appcelerator Studio开发环境,由于编译成本地代码,所以用户体验是最好的。

Xamarin

Xamarin 是微软子公司提供的一个跨平台开发软件,通过使用 C#/.NET 共享的代码库, 开发人员可以在 Xamarin 工具上,使用本地用户界面编写原生的 Android、iOS 和 Windows 应用程序, 并跨多个平台(包括 Windows 和 macOS)共享代码。


小程序、快应用

小程序

小程序开发本质上还是前端 HTML + CSS + JS 那一套逻辑,它基于 WebView 和微信自己定义的 一套 JS/WXML/WXSS/JSON 来开发和渲染页面。微信官方文档里提到,小程序运行在三端: iOS、Android 和用于调试的开发者工具,三端的脚本执行环境以及用于渲染非原生组件的环境是各不相同的:

  • 在 iOS 上,小程序的 JavaScript 代码是运行在 JavaScriptCore 中,是由 WKWebView 来渲染的,环境有 iOS 8+;
  • 在 Android 上,小程序的 JavaScript 代码是通过 X5 JSCore 来解析,是由 X5 基于 Mobile Chrome 53/57 内核来渲染的;
  • 在 开发工具上, 小程序的 JavaScript 代码是运行在 nwjs 中,是由 Chrome Webview 来渲染的。

快应用

2018 年 3 月 20 日,小米、中兴、华为、金立、联想、魅族、努比亚、OPPO、vivo、一加, 共十家手机厂商在北京联合召开快应用标准启动发布会,基于硬件平台共同推出的新型应用生态。
  快应用使用前端技术栈开发,原生渲染,同时具备 HTML 5 页面和原生应用的双重优点。用户无需下载安装, 即点即用,享受原生应用的性能体验。快应用框架深度集成进各厂商手机系统中,可以在操作系统层面实现 用户需求与应用服务间的无缝连接,提升用户的使用体验和应用服务的转化效率, 同时支持生成桌面图标等留存能力。 (快应用应该不能称为是跨平台开发方案,它只是国内手机厂商联合主导的在安卓系统层面提供快捷服务, 旨在与小程序抗衡)


Chameleon (DiDi出品)

背景:

虽然不同各端框架环境千变万化,无论各类小程序、Weex、React-Native、Flutter、快应用,它们万变不离其宗的是MVVM架构设计思想。Chameleon希望既能用一套代码完成所有端需求,将相同的业务逻辑完成收敛到同一层系统里面,又不会因为项目的抽象一致导致可维护性变差。

Chameleon原理

让MVVM跨端环境大统一:以各个跨端技术(Weex、React-Native、WebView浏览器、Flutter)和产品业务(微信小程序、快应用、支付宝小程序、百度智能小程序、今日头条小程序、其他各类小程序)的共同技术特点——MVVM架构设计, 以统一MVVM跨端架构平台为目标的程序语言框架Chameleon(任意使用MVVM架构设计的终端,都能以Chameleon开发并运行)。

View:
ChameleonSDK包括各类小程序、web端、客户端(React-Native、Weex、Flutter),目前支持微信小程序、Web、Weex三类,后续支持更多MVVM为标准的端。

View Model:
CML(Chameleon MarkupLanguage)是框架设计的一套标签语言,结合基础组件、事件系统、数据绑定,可以构建出页面的结构。同时为了降低学习成本支持类VueTemplate。

uni-app(DCloud)

uni-app 是一个使用 Vue.js 开发跨平台应用的前端框架,开发者编写一套代码,可编译到iOS、Android、H5、小程序等多个平台。

uni-app能力

功能框架

uni-app在跨平台的过程中,不牺牲平台特色,可优雅的调用平台专有能力,真正做到海纳百川、各取所长。


Fusion (Alibaba出品)

阿里中后台UI解决方案
Fusion 不仅仅是组件库,其核心是通过可配置工具实现快速定制和品牌化
Fusion 不仅仅是为前端服务的,还面向设计师,促进两者间的协作,降低沟通和复用成本
Fusion 组件库是基于 React 技术栈实现的。

1.Fusion出现背景

PC端浏览器的UI场景,交互功能都是相似的,但样式差异却很大,这些年PC端的UI变化中,变得更多的也是样式,而非交互。随着一个公司业务线的持续增长,需要建立多套网站,网站个性化需求庞大,如果每次翻新网站或者创建新的网站都需要从0~1去实现,那么人力成本,工作量无疑是巨大的,而且重复性的工作将会非常大,阿里为了解决多业务线庞大的组件需求研发了Fusion.

一般一个项目的上线流程基本都要经历,评审、设计、开发、测试 这几个阶段。

  • 评审: 业务交互,业务逻辑的评审;
  • 设计:设计规范,视觉设计,标注稿;
  • 开发:前端一般都会有一套组件库;但是组件库可能和自己业务线的品牌并不是对应的, 所以第一步需要在组件层面做 UI 的定制,然后是业务逻辑的开发;
  • 测试:最常见的就是设计师和前端坐在一起两天专门做 UI 还原度 review; 业务逻辑测试是比做流程不多说。 重复工作
  • 标黄的部分是各个业务栈间的重复工作,包括交互规范、设计规范、视觉还原、组件开发可能是重复性工作。

协同问题(UI设计师和前端人员)

  • 因为使用的工具不同对概念的认知不同;
  • 设计师的理想和前端的现实问题之间的差别
  • 每隔一段时间品牌就会升级一次,基础 UI 翻新,会有较大的工作量
  • 设计师间约定的规范没有很好的落实,已经设计好的设计稿大家共享不便
  • 已经开发好的组件没有形成很好的复用

2.Fusion能力

工作流

  • 去除重复流程,只关注业务
    • 设计师 使用的同一套规范的组件,产出的设计稿都是同一套规范。(这里使用sketch插件名字叫FusionCool)
    • 前端 不需要关注组件 UI 还原度。(还原度有问题 = 设计配置的问题)
  • 不需要再做从0~1的事情
    • 设计端使用 sketch 插件(FusionCool)在 sketch 既能设计页面,又能沉淀已经设计完成的模板
    • 开发端使用 开发工具 (Iceworks)在项目中既能使用现成的模块,又能沉淀已经开发完成的模块

组成

Fusion组成
一个组件库:@alifd/next
@alifd/next 是一套基于 React 的组件库, 我们内部 称之为骨架 DPL(Design Pattern Library)。

一个平台:fusion.design
站点提供三种能力:文档编辑、主题管理、物料托管。

两个工具:
  设计师工具 FusionCool Sketch插件
        主题发布完成后就到了 Sketch 的插件端 FusionCool, 设计师可以在 FusionCool 里面搜索 iconfont 所有素材、 使用配置好的组件、使用站点的模块模板。
  开发者工具 Iceworks客户端
        Iceworks 是淘宝飞冰团队开发的面向前端开发者的 GUI 工具,开发者无须关注环境的问题,并且有 海量物料可用。目前已经和 Fusion 的物料体系打通, 可以轻松使用 Fusion 站点的物料。

如何保证开发对设计的无差异实现

通过抽象骨架 DPL -> 通过平台定制产出定制好UI的组件、模板 -> 流入设计师的工具里面直接拖拽使用 -> 前端直接使用定制好的组件(不需关注组件UI)

  • 1.fusion.design 可以定制自己的 Design System(以下简称DS),配置主题等
  • 2.站点主题发布完成,设计师在 Sketch 的插件端 FusionCool里面搜索 iconfont 所有素材、使用配置好的组件、使用站点的模块模板,自定义配置自己的网站;
  • 3.开发者接收设计师的Config样式包的仓库。开发者可以在上面预览到设计师更新设计的所有组件样式,以及API,只需要拷贝API到代码中,就能完整还原构建者设计的组件,不需要开发新的。

Fusion 能力点

3.Fusion的技术实现

前端 Next 组件
Fusion Next 是基于 React 实现的一套 PC 端的组件库,这套组件库已经在阿里内部服务了三年。github 地址:github.com/alibaba-fus… 这次开源出来的版本是最近一年基于之前两年的使用经验、问题反馈进行重新整理和优化过。
设计师 FusionCool Sketch插件
FusionCool 底层使用 Airbnb 提供的 react-sketch 能力写成的一份 Next 组件,直接通过 DesignToken(通用变量+组件变量) 覆盖默认变量,最终在 Sketch 端实时渲染。


案例

Flutter

美团 - Flutter原理与美团的实践
闲鱼 - Release Flutter的最后一公里
闲鱼 - Flutter新锐专家之路:混合开发篇
饿了么 - 与Flutter第一次亲密接触-Android 视角

ReactNative

QQ空间-ReactNative For Android 项目实战总结
Android已有项目集成ReactNative
京东618:ReactNative框架在京东无线端的实践

WEEX

Weex在内涵段子发现页中的工程实践
网易严选App感受Weex开发
基于weex的有赞无线开发框架

Hybrid App

阅文 - 起点海外版 Hybrid App-内嵌页优化实践


拓展导读

六大顶级跨平台开发神器
开发跨平台app推荐React Native还是flutter
为什么 Airbnb 放弃了 React Native?
流言终结者- Flutter和RN谁才是更好的跨端开发方案?
Hybrid App技术解析 -- 原理篇
ReactNative源码分析之JS渲染成Android控件
探索Virtual DOM的前世今生 聊聊移动端跨平台开发的各种技术

前端能力中台化之路-李正韬.pdf
阿里重磅开源中后台UI解决方案Fusion
阿里巴巴的 Fusion Design 是如何运作的?
Chameleon跨端框架——壹个理想主义团队的开源作品
chameleon跨端实践经验分享-杨益良.pdf