基于最近考虑着手iOS 安卓 双平台的开发,整理了一下现存的一些跨平台开发思路。
为了让自己更直观的感受不同跨平台思路的差异,我简单的做了几个图示。
套壳模式
微信公众号H5(相当于) , jQuery Mobile ?
套壳模式是开发APP可以说是最简单快捷的(对于web开发者来说),基本上只要有一个正常能用的手机端可以UI适应的web就可以通过套一个壳完成APP开发。 套壳的问题主要有2个
- 体验不好,完全通过套壳的webapp 从性能以及UI交互上来说都会比原生app差,通过对js、css的优化,可以解决一部分,比如说click事件在手机端应当用tap事件(封装tap事件),另一部分解决不了,比如说iOS端的侧滑返回或侧滑删除功能,这个体验如果要靠js来实现,效果当然是可以写出来的,但是流畅度、细节表现大大不如原生,而且会花费比较多的时间,而且没有什么这一块比较好的库可以用。
- 没有原生功能支持,在微信公众号h5中,还可以通过微信的JSAPI调用部分微信提供的功能,譬如说存储图片。但是套壳在app里的时候,就完全没有办法支持了。
Web 框架模式
Dcloud H5 plus (SDK)
除了Dcloud h5 目前没有发现明确的web框架模式,这里的web框架模式主要是指以web形式开发,通过特定的SDK或者插件api访问app原生功能,不需要使用该框架特定的打包流程,支持以sdk嵌入等方式构建app的。
Web框架模式相对来说简单,快速。不用深入学习原生的内容即可快速使用原生平台的能力,通过插件的扩展也能提高一定程度上的体验效果。
那这种开发模式有没有缺点呢,实际上缺点和主要还是在体验方面,以及扩展性方面。 首先web框架模式主要还是以套壳的形式来开发,这样就导致了需要用web和bridgeSDK来实现几乎所有的需求,在很多时候很难达到原生的性能和效果,当然有些甚至难以实现。 如果我们希望在某些部分进行优化的时候,我们不得不寄希望于SDK本身,而如果sdk本身不够优秀,就会对我们的开发产生较大的制约。 以 DCloud H5 Plus为例,该框架的思想还停留在网页开发的思路,其传递参数或是共享数据的方式依然是通过页面跳转传参或者使用localstorage,这在APP开发中就显得捉襟见肘。 其提供的绝大多数api几乎就是原生api的缩减翻译功能,丢失了很多细节(创建对象简单、但失去了很多可配置性接口),同时也没有任何改良。 造成这两大问题在我看来主要还是因为该产品团队应该是长期开发web程序,有强烈的web模式限制所致,对于客户端开发的模式以及很多特性了解不足
插个题外话,如果我们对某个系统api进行封装,我们要做的不是仅仅把字符变短,变的好看,那是没有意义的。更重要的是,我们应该封装一些有价值的操作细节。例如对于系统的存储功能,我们可以封装出一个cache,封装出一个类型解析,或者是对于文件结构的自动化处理(创建、删除等)。 这我们才能说是有价值的封装。
编译框架模式
React Native, Fluter, Weex, Uni-app
编译前端这块感觉有时候可能是野心太大,忘了初衷,现在的编译前端框架层出不穷,却给人带来了越来越多的负担。 一个养殖场为了同时产出鸡蛋和鸭蛋,而且尽可能的成本要低一些,采用的做法最终变成了生物科技公司,做出一个可以同时下两个蛋的物种。可是鸡蛋和鸭蛋的质量或者健康想要管理起来就更麻烦了,因为你要回去改基因。
从实际的开发角度来说,编译框架依赖于框架提供的编译器来生成APK,IPA包,背景雄厚的还好说,如果是不那么可靠的框架,很有可能是跟不上平台的步调的,毕竟现有的各平台已有的很多特性和功能、这些框架都没有或者完善的解决。 你没有办法直接从鸡和鸭来解决你遇到的问题,你需要先修改基因(写插件),而你修改基因的时候,不仅需要了解(深入)原生平台的特性、还需要了解基因公司的基因工程技术(框架的插件设计方法和未知的坑)。
在我看来,这个部分如果你没有比较强的实现能力,你是很难从网上获取到你需要的非官方功能的支持。而如果你使用原生的语言来写,你仅仅通过官方文档甚至是搜索引擎的复制粘贴,就可以实现绝大多数功能了。
思考
好的跨平台方案是什么? 好在哪里?
实际上在游戏领域,我们有着非常成熟、广泛被接收,并且没有不可调和的坑的跨平台方案。(主要说移动端) 譬如说 COCOS2DX, UNITY3D 这两个框架主要是游戏领域,而且具有广泛的影响力,那他和我们的App跨平台方案有什么不同呢?为什么移动应用领域内没有这样的框架呢?
游戏在整个手机的使用中,只是其中一个很小的特殊部分,尽管他可能占用了大部分时间。 游戏的底层抽象程度足够高,对于系统的(UI、交互API)依赖程度非常低,极端一些来说只要实现了渲染、音频、触控、键盘再加上一定的游戏业务编程能力就可以支持绝大部分游戏的制作开发了,如果游戏已经是自己渲染的画面了,那还需要系统提供的界面吗? 真的就不需要了。 所以游戏引擎可以无视掉大部分系统提供的UI和对应的交互以及大量与游戏无关的系统接口,安心的专注于特定领域的精进就可以了。 所以游戏引擎能够保证框架本身的及时性、可靠性、以及效率。
而APP开发就五花八门了,并且很多时候由于和系统提供的APP共存,无论是从开发效率上还是从用户上手角度来说,使用系统提供的api以及符合系统操作习惯基本上都是难以绕过的,那一旦涉及到APP跨平台开发,也就意味着需要同时维护多平台的绝大部分特性。想要做好跨平台APP框架,这对于任何一家公司的某个业务开发部门来说,都是个巨大的考验。
为什么要跨平台开发? 归一性的原因是什么??
一招鲜吃遍天?首先我认为这个思路是最不可取的, learn once, write anywhere. 只是一个幻想,当然 learn AI once, let computer write anywhere 学好人工智能,让电脑自己写以后倒是更有可能性一点。 我这样认为的原因十分简单,我们现在使用的编程语言已经是经过了非常多层的封装和演化而来的高级语言,如果只是为了精神强迫症去做特定语言的跨平台,那就和为了吃到更好吃的菜非要自己在家买种子种菜一样,本末倒置了。
减少开发成本?这当然是所有企业和工程师都追求的,这是最核心的原因吗?我们现在的各类方法有效的实现了目标了嘛?未来真的可期嘛?
怎么实现? 怎么实现是最科学的??
Web补充模式
归根结底,我们希望通过跨平台的方式减少甚至是抹去多平台开发所带来的额外成本,理想是好的,但现实却很残酷,安卓和苹果就像曾经的windows和mac总是在不同的路上越走越远,就像三国那句名言,天下大势合久必分分久必合,当你历经千年好不容易统一的时候,你发现还有海外,哪怕是现在的地球村,还有人作妖闹贸易制裁耍政治流氓。 在远一些的未来,我们甚至可能还是会发现,体系之外还有不同的体系,毕竟只有0没有1,就没有世界。 如果差异是不可能被抹除的,那为什么不放下执念,想一想初心呢。 我们使用web的初衷是因为简单、快、通用,那为什么要让他去从事那些复杂,不必通用的事情呢? 甚至是再开发一个语言,让本来就有3个语言的跨平台开发变成了4个甚至更多。 是的,我更加认可的跨平台开发方式,就是使用web技术来作为通用简单、但是却耗费工作量的部分来减少工作成本。 譬如说,不太注重交互和高性能的信息展示,富文本的展示页,动态生成或者多字段表单页,需要支持热更新的闪屏等。 我们仍然可能在这些页面有一定的原生支持,但是这些需求是十分有限的。比起大量的原生api支持,其实webview和原生APP之间,更需要的是数据的互通。 比起复制不同国家的各一万个邮票,我觉得能保证信件及时有效到达目的地的传递方式更有意义。
“在我使用DCLOUD H5 产品时,他们在这个我认为很重要的层面就做的很不好,加上提供的UI逻辑与class耦合严重,我直接放弃了这个产品以及对他们后续产品有了很重的阴影。”
“web补充模式”和“web框架模式”其实本质上没有太大区别,都是需要web开发和原生开发一起使用的。 最大的差异就在于web和原生各自所占比例。 可以说是思路上的差别,模式本身是相同的。
Web补充模式开发计划
这里主要也是为自己后续做一些准备:
基本要求: 逻辑与表现分离 web与native之间的通用响应机制 web与native之间的通用数据访问( 全局变量的访问 )
模块构思 ( 考虑到有的时候我们可能有不希望webview拿到的数据,所以可能需要scope的概念 ) SData 共享数据( 全局变量共享 ) -> SDStorage -> SDCache -> SDConfig
Delegate APP代理 通过APP代理,定义需要被处理的消息,同时接受到消息之后,负责调用对应的方法来响应。
Notifier 通知者 Notifier.toApp 向native发送通知 Notifier.toWeb 向web发送通知