最近出现的ReactNative再次让跨平台移动端开发这个话题火起来了,曾经大家以为在手机上可以像桌面那样通过Web技术来实现跨平台开发,却大多因为性能或功能问题而放弃,不得不针对不同平台开发多个版本。

但这并没有阻止人们对跨平台开发技术的探索,毕竟谁不想降低开发成本,一次编写就处处运行呢?除了ReactNative,这几年还出现过许多其它解决方案,本文我将会对这些方案进行技术分析,供感兴趣的读者参考。

j2objc

为了方便讨论,我将它们分为了以下4大流派:

Web流:也被称为Hybrid技术,它基于Web相关技术来实现界面及功能

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

编译流:将某个语言编译为二进制文件,生成动态库或打包成apk/ipa/xap文件

虚拟机流:通过将某个语言的虚拟机移植到不同平台上来运行

Web流

Web流是大家都比较了解的了,比如著名的PhoneGap/Cordova,它将原生的接口封装后暴露给JavaScript,可以运行在系统自带的WebView中,也可以自己内嵌一个Chrome内核。

作为这几年争论的热点,网上已经有很多关于它的讨论了,这里我重点聊聊大家最关心的性能问题。

Web流最常被吐槽的就是性能慢(这里指内嵌HTML的性能,不考虑网络加载时间),可为什么慢呢?常见的看法是认为「DOM很慢」,然而从浏览器实现角度来看,其实DOM就是将对文档操作的API暴露给了JavaScript,而JavaScript的调用这些API后就进入内部的C++实现了,这中间并没有多少性能消耗,所以从理论上来说浏览器的DOM肯定比Android的「DOM」快,因为Android的展现架构大部分功能是用Java写的,在实现相同功能的前提下,C++不大可能比Java慢(某些情况下JIT编译优化确实有可能做得更好,但那只是少数情况)。

所以从字面意思上看「DOM很慢」的说法是错误的,这个看法之所以很普遍,可能是因为大部分人对浏览器实现不了解,只知道浏览器有DOM,所以不管什么问题都只能抱怨它了。

成都APP开发

那么问题在哪呢?在我看来有三方面的问题:

早期浏览器实现比较差,没有进行优化

CSS过于复杂,计算起来更耗时

DOM提供的接口太有限,使得难以进行优化

第一个问题是最关键也是最难解决的,现在说到Web性能差主要说的是Android下比较差,在iOS下已经很流畅了,在Android4之前的WebView甚至都没有实现GPU加速,每次重绘整个页面,有动画的时候不卡才怪。

浏览器实现的优化可以等Android4.4慢慢普及起来,因为4.4以后就使用Chrome来渲染了。

而对于最新的浏览器来说,渲染慢的原因就主要是第二个问题:CSS过于复杂,因为从实现原理上看Chrome和AndroidView并没有本质上的差别,但CSS太灵活功能太多了,所以计算成本很高,自然就更慢了。

那是不是可以通过简化CSS来解决?实际上还真有人这么尝试了,比如Famo.us,它最大的特色就是不让你写CSS,只能使用固定的几种布局方法,完全靠JavaScript来写界面,所以它能有效避免写出低效的CSS,从而提升性能。

而对于复杂的界面及手机下常见的超长的ListView来说,第三个问题会更突出,因为DOM是一个很上层的API,使得JavaScript无法做到像Native那样细粒度的控制内存及线程,所以难以进行优化,则在硬件较差的机器上会比较明显。对于这个问题,我们一年前曾经尝试过嵌入原生组件的方式来解决,不过这个方案需要依赖应用端的支持,或许以后浏览器会自带几个优化后的WebComponents组件,使用这些组件就能很好解决性能问题。

现阶段这三个问题都不好解决,所以有人想干脆不用HTML/CSS,自己来画界面,比如Reactcanvas直接画在Canvas上,但在我看来这只是现阶段解决部分问题的方法,在后面的章节我会详细介绍自己画UI的各种问题,这里说个历史吧,6年前浏览器还比较慢的时候,Bespin就这么干过,后来这个项目被使用DOM的ACE取代了,目前包括TextMirror和Atom在内的主流编辑器都是直接使用DOM,甚至W3C有人专门写了篇文章吐槽用Canvas做编辑器的种种缺点,所以使用Canvas要谨慎。

另外除了Canvas,还有人以为WebGL快,就尝试绘制到WebGL上,比如HTML-GL,但它目前的实现太偷懒了,简单来说就是先用html2canvas将DOM节点渲染成图片,然后将这个图片作为贴图放在WebGL中,这等于将浏览器中用C++写的东东在JavaScript里实现了一遍,渲染速度肯定反而更慢,但倒是能用GLSL做特效来忽悠人。

硬件加速不等同于「快」,如果你以为硬件加速一定比软件快,那你该抽空学学计算机体系结构了

其实除了性能问题,我认为在Web流更严重的问题是功能缺失,比如iOS8就新增4000+API,而Web标准需要漫长的编写和评审过程,增加4000API我这辈子是等不到了,即便是Cordova这样自己封装也忙不过来,所以为了更好地使用系统新功能,写Native代码是必须的。

P.S.虽然前面提到HTML/CSS过于复杂导致性能问题,但其实这正是Web最大的优势所在,因为Web最初的目的就是显示文档,如果你想显示丰富的图文排版,虽然iOS/Android都有富文本组件,但比起CSS差太远了,所以在很多Native应用中是不可避免要嵌Web的。

代码转换流

前面提到写Native代码是必须的,但不同平台下的官方语言不一样,这会导致同样的逻辑要写两次以上,于是就有人想到了通过代码转换的方式来减少工作量,比如将Java转成Objective-C。

这种方式虽然听起来不是很靠谱,但它却是成本和风险都最小的,因为代码转换后就可以用官方提供的各种工具了,和普通开发区别不大,因此不用担心遇到各种诡异的问题,不过需要注意生成的代码是否可读,不可读的方案就别考虑了。

成都APP开发:j2objc在APP开发中有什么作用

接下来看看目前存在的几种代码转换方式。

将Java转成Objective-C

j2objc能将Java代码转成Objective-C,据说Google内部就是使用它来降低跨平台开发成本的,比如GoogleInbox项目就号称通过它共用了70%的代码,效果很显著。

可能有人会觉得奇怪,为何Google要专门开发一个帮助大家写Objective-C的工具?还有媒体说Google做了件好事,其实吧,我觉得Google这算盘打得不错,因为基本上重要的应用都会同时开发Android和iOS版本,有了这个工具就意味着,你可以先开发Android版本,然后再开发iOS版本。。。

既然都有成功案例了,这个方案确实值得尝试,而且关键是会Java的人多啊,可以通过它来快速移植代码到Objective-C中。

将Objective-C转成Java

除了有Java转成Objective-C,还有Objective-C转成Java的方案,那就是MyAppConverter,比起前面的j2objc,这个工具更有野心,它还打算将UI部分也包含进来,从它已转换的列表中可以看到还有UIKit、CoreGraphics等组件,使得有些应用可以不改代码就能转成功,不过这点我并不看好,对于大部分应用来说并不现实。

由于目前是收费项目,我没有尝试过,对技术细节也不了解,所以这里不做评价。

将Java转成C#

Mono提供了一个将Java代码转成C#的工具Sharpen,不过似乎用的人不多,Star才118,所以看起来不靠谱。

还有JUniversal这个工具可以将Java转成C#,但目前它并没有发布公开版本,所以具体情况还待了解,它的一个特色是自带了简单的跨平台库,里面包括文件处理、JSON、HTTP、OAuth组件,可以基于它来开发可复用的业务逻辑。

比起转成Objective-C和Java的工具,转成C#的这两个工具看起来都非常不成熟,估计是用WindowsPhone的人少。

将Haxe转成其它语言

说到源码转换就不得不提Haxe这个奇特的语言,它没有自己的虚拟机或可执行文件编译器,所以只能通过转成其它语言来运行,目前支持转成Neko(字节码)、Javascript、Actionscript3、PHP、C++、Java、C#和Python,尽管有人实现了转成Swift的支持,但还是非官方的,所以要想支持iOS开发目前只能通过AdobeAIR来运行。

在游戏开发方面做得不错,有个跨平台的游戏引擎OpenFL的,最终可以使用HTML5Canvas、OpenGL或Flash来进行绘制,OpenFL的开发体验做得相当不错,同一行代码不需要修改就能编译出不同平台下的可执行文件,因为是通过转成C++方式进行编译的,所以在性能和反编译方面都有优势,可惜目前似乎并不够稳定,不然可以成为Cocos2d-x的有利竞品。

在OpenFL基础上还有个跨平台的UI组件HaxeUI,但界面风格我觉得特别丑,也就只能在游戏中用了。

所以目前来看Haxe做跨平台游戏开发或许可行,但APP开发就别指望了,而基于它来共用代码实在就更不靠谱了,因为熟悉它的开发者极少,反而增加成本。

XMLVM

除了前面提到的源码到源码的转换,还有XMLVM这种与众不同的方式,它首先将字节码转成一种基于XML的中间格式,然后再通过XSL来生成不同语言,目前支持生成C、Objective-C、JavaScript、C#、Python和Java。

虽然基于一个中间字节码可以方便支持多语言,然而它也导致生成代码不可读,因为很多语言中的语法糖会在字节码中被抹掉,这是不可逆的,以下是一个简单示例生成的Objective-C代码,看起来就像汇编

相关阅读:

开发移动游戏软件需要哪些步骤

成都企业软件开发测试该怎么进行?优点是什么

成都APP开发:火山小视频APP开发具有哪些优势

评论

电子邮件地址不会被公开。