目前可供选择的混合应用开发框架大致可以分为五类:基础框架、脚手架、原生编译框架、开发平台、自研框架。
基础框架
基础框架是指以 WebView 与原生 API 交互为核心的经典混合应用开发框架,典型代表是 Cordova、Phonegap,早期还有 Interl XDK,不过已经停止维护。
Cordova 提供了跨平台的交互机制、插件机制,理论上可以在框架基础上实现任意混合开发需求。但它也存在我们在第01课中提到的两大问题,第一:前端只能做成 SPA;第二:插件生态相对不够丰富。带来的结果就是前端交互体验受限,另外部分个性化需求可能需要自己开发原生插件,需要额外的原生力量投入。开发成本视需求而定,性能体验比较差,基本上无法用于商业产品,仅适合简单的信息展示类或者工具类 App 项目。
脚手架
脚手架是指在基础框架的基础上做 UI 层封装,典型代表是 Ionic,其底层仍然是 Cordova,使用 Angular 封装了整套样式、插件,只对开发者暴露 Angular 层面的语法。相对基础框架来说,脚手架提供了整套 UI 组件和交互插件,使开发者可以摆脱界面开发,专注于业务逻辑,能有效提高 App 开发速度。
脚手架并没有解决基础框架 Cordova 存在的两个核心问题,Ionic 也是采用 HTML5 动画转场,在低端机上普遍表现不佳;插件生态也需要依赖 Cordova 插件库。此外,还为开发者增加了 UI 层框架的学习成本。如果不介意基础框架的缺点,同时能接受框架自带 UI 风格,或者 UI 开发能力偏弱,那么选择脚手架可以更快速地开发出 UI 精致的混合应用。
原生编译框架
所谓原生编译框架,是指使用特定语法开发,经过编译产出跨平台原生 App 的开发框架。目前比较流行的有 ReactNative、Weex、NativeScript,它们都使用 JavaScript 作为开发语言。UI 层语法(框架)稍有区别,分别是 React、Vue、XML,但它们的共同点是,UI 层都提供了一套标签体系,这是最终能将 App 原生化的前提。编译引擎在处理代码时会将标签转换成对应的原生组件,这一点其实也跟微信小程序非常类似。
这种理念相比经典混合方案更为先进,一步到位地解决了开发效率和应用性能问题,开发效率虽不及经典模式,但比原生开发还是要快上不少。但并不能说这是完美的解决方案,因为这种方案的本质是一场用自有标签操控原生组件的“木偶戏”,标签体系的丰富度和可定制性将直接制约开发需求能否顺利实现。当某种需求无法用标签实现时,就需要以各种形式引入原生能力,一方面这会降低开发效率,另外这对不具备原生开发能力的开发者来说,则是一个无法逾越的致命障碍。
虽然这类框架都支持插件机制,但 ReactNative 和 Weex 都没有官方维护的原生插件生态,这使开发者查找和鉴别插件非常不便,而且就开发者的反馈来看,其框架自身以及插件都有不少坑,不懂原生开发很难玩转得转。
针对这一问题,NativeScript 建立维护了一个相当完善的官方插件生态,开发者可以很方便的在这里查找模块,对不具备原生开发能力的开发者来说,某个需求能不能实现,查一下就知道。但是这个框架在国内不算流行,入坑可能有一定风险,不建议新手淌坑。
总结一下,原生编译框架的开发效率介于原生开发和混合开发之间,App 性能也介于原生开发和混合开发之间,需要同时具备前端开发能力和原生开发能力,适合技术储备足够、产品开发节奏相对较快的团队。
开发平台
开发平台是指将 App 开发的整个生命周期都放在云端的一种开发方式,开发者需要做的仅仅是写代码、上传代码、下载安装包,其他配置都可以在平台上操作,AppCan、DCloud、APICloud 都属于这一类。
这种模式是在 Cordova 流行之后,国内厂商针对其缺陷改进而来的,使用多页+原生转场替换前端动画,提供官方维护的插件库,可视化管理几乎所有的开发配置,尽可能降低开发门槛。
它们的优点非常明显,极大幅度的降低了 App 开发成本,甚至开发 iOS 应用都不需要 Mac 电脑,得益于开发者都集中在国内,插件的丰富程度和社区的本土化也都做的不错,可以说这完全是为前端开发者量身打造的混合应用开发方案。
其底层仍然是经典混合开发模式,开发语言就是前端语言,开发效率可以得到保证,但缺点也主要集中在前端语言的体验瓶颈上,另外多页面加载虽然解决了动画流畅性问题,但却带来了每次载入新页面的加载延迟,这些都需要在开发中着重优化。另外代码放在云端理论上存在不可控因素(DCloud 支持本地打包),对这一点比较敏感的项目可能不适合选择平台模式。
自研框架
自研框架是指结合 App 项目需求,由原生团队自主研发混合应用框架,以满足最符合项目预期的开发效率和灵活性。比如可以将部分模块嵌入 WebView 由前端实现以缩短开发周期,或者直接载入 URL 满足灵活的内容更新需求。
这种方式的优点在于可以任意调整混合比例,实现成本和效率的平衡。虽然也算一种混合开发方式,但团队建制上依然是传统的原生+Web,比较适合原生开发能力充裕的团队。
横向对比
从一个前端开发者的角度看,以上框架的对比结果是这样的:
开发快不快、上手难不难、效果好不好,是做技术选型最优先考虑的三个要素。其中开发效率和性能体验属于框架的客观属性,这两方面的表现通常不会因为开发者的原因而发生太大改变,上图中这两列的分值越高,说明效率越高、性能越好;上手难度则有一定主观性,不同开发者由于能力或习惯不同,可能会产生完全不同的主观印象,以上打分仅供纯前端开发者参考,分值越高,说明上手难度越低。
从开发效率上来看,由高到低依次是“开发平台 > 脚手架 > 基础框架 > 编辑框架”。对比的基本逻辑是这样的,前三位都是用传统前端语言开发,默认开发效率高于非前端语言。其中脚手架由于提供了 UI 层封装,所以效率高于基础框架;开发平台在基本组件封装的基础上,还提供了一站式的开发体验,效率又高于脚手架。根据自己的实际情况也可能有不同的结论,如果你使用 React Native 超溜的话,开发效率也许不比其他方式低。
上手难度的对比结果显示,“编译框架 > 脚手架 > 基础框架 > 开发平台”,上手难度依次降低。这个结果完全出自前端视角,基本逻辑是非纯前端开发的编译框架难度最高,脚手架因为增加了 UI 层框架的学习成本,所以理论上难度高于基础框架,基础框架因为强制要求 SPA,所以理论上难度高于多页面模式的开发平台。这方面本来就是“会者不难,难者不会”,所以没有太多好说的。
性能体验方面,由高到低的排名依次是“编辑框架 > 开发平台 > 脚手架 > 基础框架”,遵循的排名逻辑是原生编译的性能要高于前端渲染。后三位中,开发平台由于引入原生转场动画,所以理论上体验优于另外两种;脚手架和基础框架在体验上其实没有可以拿出来做比较的点,都是纯前端呈现界面,原生交互的实现也一样,它俩的排名没有价值,可以忽略。
注:自研框架灵活性较强,无法直接与其他框架对比。
为什么选择 APICloud
了解了各种框架的大致特点后,作为前端开发者肯定更倾向于无需依赖原生技术栈的云平台模式,目前国内已知的平台有 AppCan、APICloud、DCloud,它们的功能大同小异,表面上看几乎只有 API 命名的区别,从这个角度讲选哪家都是可以的。
相比之下 APICloud 的开发完成度更高,引擎 Bug 更是很少。与 DCloud 相比,APICloud 平台的周边功能更为完善,这应该是目前上手难度较低的混合应用开发框架,后面的实战课程都将基于 APICloud 平台展开。
HelloWorld
如果你是第一次打开 APICloud 官方文档,会发现满屏幕的概念、名词,不知该从哪儿看起,这是正常的,官方文档确实有这个效果,我们先不管那么多,先来做一个 HelloWorld 项目上手体验一下。
进入平台,首先我们在平台上建立一个项目,进入项目页面后,可以看到左侧导航“端开发”部分,这里包含了我们开发中会用到的所有功能,它们分别是 App 的常规设置、证书设置、代码管理、模块管理和最后的编译打包功能,走完这套流程,我们应该可以在“云编译”这一步里得到一个打包好的 App,扫码下载安装到手机上。
1. 用什么开发工具?
官方开发工具是 APICloud Studio 2,各项功能十分齐全。但作为编辑器,它实在不太好用,建议使用自己顺手的编辑器开发,仅把 APICloud Studio 用作同步工具。或者你也可以给自己的编辑器加上插件实现同步功能,目前 Sublime、Atom、Eclipse、WebStorm 都有相应的插件。
2. 怎么检出代码?
APICloud 平台默认会为每个项目分配一个 SVN 地址,SVN 用户名就是你的 APICloud 平台账号邮箱,密码可以从控制台的“端开发-代码”页面获取到。
3. 目录结构有限制吗?
没有,只要根目录下存在 config.xml
文件,就是一个合法的 APICloud 项目,唯一可能的限制是当你要使用加密数据功能时,必须将加密文件 key.xml
存放在根目录 /res
文件夹下,这个约束是平台开发者偷懒造成的结果,但无论如何这个路径暂时是固定的。
4. 怎么调试?
调试方式首推 WiFi 同步+真机预览,可以既兼顾效率又保证预览结果准确性,整套流程是这样的:
APICloud平台新建项目
|
配置项目所需模块
|
编译自定义 loader 并安装
|
本地检出代码
|
IDE 开启 WiFi 同步
|
开始开发
|
开发中 WiFi 增量同步实时预览结果
真机预览需要在手机上安装一个 loader,用来跟 PC 端的 IDE 建立连接同步代码,并在手机上运行代码,模拟真实打包效果。
loader 分为官方 loader 和自定义 loader,它们的区别在于,官方 loader 只集成所有官方模块,不包括第三方模块,自定义 loader 则会集成我们项目中真实添加的模块,只有 loader 中集成的模块预览时才能生效,显然自定义 loader 是开发调试更好的选择。
开发过程中想要预览效果,可以在 Studio 界面通过快捷键 Ctrl+I,将代码增量同步到手机,这将是我们今后开发中最常用的一个快捷键。另外,开发期间建议手机连上充电器,避免手机自动锁屏,锁屏状态或者 loader 应用不在前台,都无法同步代码。还有一点需要注意,实现 WiFi 同步的前提是你的手机和 PC 要在同一个局域网内。
还有一些其他调试方法,可以自己酌情使用:
文件实时预览。在 IDE 左侧文件列表中选中一个 HTML 文件右键单击,弹出菜单中有一个“实时预览”,点击会以浏览器窗口的形式打开当前 HTML 文件。这个功能跟拖动 HTML 文件在浏览器中打开效果一样,只能预览 Web 自身功能,原生模块无法预览。这个 IDE 的弹出窗口还有个特点,它会一直保持在桌面最上层,如果你的显示屏够大还好,否则就会始终挡住一块编辑器区域,所以我觉得这个功能不是很好用,只适合偶尔看一下布局。
USB 同步。只适用于安卓机,需要 PC 已经装好手机驱动,且手机要开启开发者模式,允许 USB 调试。同步过程就是通过 USB 线缆给手机发送一个安装包并自动安装,最终效果跟 WiFi 同步是一样的,但除了可以不依赖 WiFi 以外,没有任何优势,不建议使用。
模拟器预览。算是 USB 同步的改进版,把 USB 连接的真机换成了当前 PC 开启的安卓模拟器,理论上比 USB 同步方便了很多,但实际上安卓模拟器比较吃性能,普通 PC 跑模拟器通常都不太流畅,而且模拟器环境跟真机环境往往有差异,不能保障预览结果的准确性,除非你找不到一个用来测试的安卓手机,否则也不建议使用。
进阶问题
能不能用 Vue 开发?
多页面开发模式利用原生动画解决了 App 转场流畅性问题,但也让开发体验变得零碎而杂乱,那混合应用能不能跟现代前端框架结合呢?以 Vue 为例,我认为有两种可能的结合方式。
保持多页面的开发方式,Vue 只负责页面渲染,充当响应式模板引擎。这种做法的优点是可以保留原生转场动画,缺点是每个页面都要加载 Vue。而多页面混合应用的性能瓶颈之一就是页面文件的加载,每个页面都加载 Vue,对于 Vue 框架功能利用率不高的页面,就不符合性能优化原则了。所以建议仅当遇到个别复杂页面时,单独引入 Vue 以提升开发效率,普通展示类页面可以使用更精简的前端模板引擎渲染。
放弃多页面模式,整体做成单页面应用。优点是可以最大化发挥 Vue 的开发优势,而且可以配合 Webpack 之类的自动化开发工具,缺点是无法使用原生转场,这一点是致命的,因为 HTML 5 转场动画目前仍然无法达到商用标准。如果无视这个问题,倒是可以这么做。
JS 插件和原生组件怎么选择?
通常来说,原生组件总是要比 JS 插件运行更流畅。而且某些特殊功能只能用原生组件实现,比如某些页面需要一打开立即使输入框获得焦点并弹出软键盘,这个需求纯前端实现会有严重的兼容问题,但如果用 UIInput 原生组件实现就很容易;
原生组件还有一个优势,即通常不会被其他原生元素遮挡,这个问题经常出现在有 Frame 窗口的页面中,Frame 本身就是一个覆盖在页面上的原生组件,层级高于前端内容,此时我们想在页面上显示一个弹窗,用 JS 生成一个弹窗肯定会被遮挡,只能用原生组件来实现。
但原生组件在使用时往往不如 JS 插件方便。原生组件的样式只能通过组件提供的配置来修改,如果组件提供的配置不够,那就意味着无法修改到满意的样子。
APICloud 模块库里的 UI 组件默认样式没有能用的,大部分必备模块也只能通过配置做到勉强能接受的程度,比如 dialogBox ,通常我宁愿用系统默认弹窗也不会用它,而这可能是目前模块库中唯一的弹窗组件。另外某些原生组件不会随 Window 关闭而关闭,比如百度地图,关闭页面时需要手动调用地图关闭方法,否则百度地图会一直出现在屏幕上。