为什么移动端跨平台开发不靠谱?

10,243 阅读18分钟

前言

翻墙偶然读到一篇不错的文章,随手翻译,作者是jielse发表于androidHub。

台风过后的城市

随着智能手机的发明,许多开发人员都提出了同样的问题:如何为多个移动平台构建和发布应用程序? 包括最初的iPhone和BlackBerries,Android,以及Windows Phone和Web。 每个平台单独发布应用程序是很昂贵的。我们最初的想法: 肯定有一个解决方案可以降低开发多个应用的成本。但是事实是不是这样的呢?

在Pixplicity,超过六年来,我们一直在开发应用,并且企图解决这个问题。结局并没有什么不同:虽然我们在提供全方位解决方案之前,就开始专门用本地开发人员开发Android。多年来,我们尝试并测试了许多跨平台解决方案,如PhoneGap,Xamarin和React。 最后,我们决定采用Android和iOS的本地解决方案。 具体的原因会在下文解释。

那么这个跨平台又是什么呢?

iOS应用程序传统上用Objective-C或Swift编写; Android应用程序用Java或Kotlin。 这些都是原生语言。 这意味着如果你想为两个平台制作应用程序,则需要至少知道两种编程语言。 将web添加到组合中,你将需要用于UI的HTML + CSS + JavaScript,以及用于业务逻辑的PHP或Ruby类。 那将是很大的工作量。

跨平台解决方案旨在通过为多个平台使用单一编程语言来简化(部分)此问题。

这些解决方案可以分为两类:

1.使用所有平台支持的Web技术的。 这些解决方案基本上加载了应用程序中的移动浏览器,并在该浏览器中执行所有逻辑,同时提供传统网站技术没有的附加功能,例如推送通知或访问文件存储。 这个类别包括PhoneGap(或Cordova),Sencha和Ionic(一个构建在PhoneGap之上的框架),并使用JavaScript作为主要的编程语言。

2.另一类通常被称为“本地跨平台”,因为程序员编写的代码由程序自动转换为本地代码。 这具有以下优点:所产生的应用程序可以实现近乎原生的性能,而基于Web的解决方案则具有在浏览器中运行未编译的代码的开销。 这个类别包括React Native和(可能)最流行的一个:Xamarin。

这些本地跨平台解决方案可以进一步分为

两个类别:

1.共享UI代码(应用程序的可视部分)和不具有这些子类别的子类别。例如,常规的老Xamarin在平台之间共享业务逻辑代码,但UI代码(和其他特定于平台的代码)是专门为每个平台编写的。 即使作为开发人员,你正在使用单一语言(在这种情况下为C#),你仍然在iOS和Android上为UI编写单独的代码。

2.Xamarin还提供了一个名为Xamarin.Forms的API,可以共享UI代码。 不用编写单独的UI代码,而是使用Xamarin.Form自己的标记格式来编写它,然后将其转换为本机控件。 React也属于这一类; 而不是编写本机视图,将会写出“React”视图。

只用编写一次UI代码,React代码

优点

所有这些技术都相当漂亮。共享代码意味着更少的工作和更少的学习,让我们来看看使用上述选项之一的好处:

1.共享业务逻辑 - 将业务逻辑写入一次,在任何平台上运行。 Google通过使用自己的Java对Objective-C转换器J2ObjC,在Android,iOS和Web应用程序中重新使用其70%的代码。这大大减少了构建应用程序所需的工作量,降低了成本,并缩短了发布时间。 2.维护 - 共享代码不仅降低了初始构建期间的成本,而且对你的应用程序的使用寿命也将是有益的。 3.学习一门语言 - 如果你是一名寻求多个平台的开发人员,那么学习单一语言(或一组语言(通常是一种编程语言,构建脚本语言和用户界面的标记语言)比两套更容易。 4.同一个团队在两个应用程序上工作 - 这是一个很大的工作。一个团队经费更便宜,使项目管理更容易,更高效地工作。知识在团队中更容易分享。 Android团队的成员可以帮助iOS团队,反之亦然,因为没有Android团队,没有iOS团队。只有一个团队 共享单元测试 - 如果你有单元测试,跨平台代码库还可以共享单元测试。这意味着在写测试时花费的时间更少。 5.与网络一起使用 - 当使用基于Web的解决方案(或支持网络的本机)解决方案时,所有上述规则也适用于Web平台。 Xamarin只能在iOS和Android上共享代码的地方,基于网络的工具在你的应用程序的网页版本之前提供了所有的优点。

显然,无论你是单一的开发人员,跨多个开发团队的跨国公司,还是学习构建你的第一个应用程序的学生,都可以从这些优势中获益很多。 “写一次,无处不在”它经常被引用,虽然我不会认为它有时是项目的完美解决方案,但这听起来太好了。

——by谷歌高级软件工程师Chet Haase

多年来,Pixplicity的团队和我使用了几个平台(不同程度的成功),我们可能不会再停止尝试新的平台。一路上,我们遇到了一些重大的陷阱,我认为在提交跨平台工具之前应该仔细考虑。

缺点

所有的大公司都是跨平台的吗? Google创建并使用(很多)J2ObjC。 Facebook创建并积极维护React。微软收购并非常积极地维护Xamarin。

1.不同的平台是不同的

你无法为一个平台构建应用程序,并希望在将其复制粘贴到另一个平台上时获得良好的评分。我知道你想要,虽然你技术上可以,但你不应该这样做。 Android和iOS是不同的,Android和iOS用户是不同的,他们应该接近不同。每个平台都有自己的设计指南和规则来开发,用户会知道你什么时候破坏他们。

正如谷歌所说:

J2ObjC不提供任何类型的平台无关的UI工具包,也没有计划在未来这样做。 我们认为iOS UI代码需要使用Apple的iOS SDK(使用Android API的Android用户界面,使用GWT的网络应用程序UI等)Objective-C,Objective-C ++或Swift中编写。

Facebook,在React的官网上写道:

值得注意的是,我们没有追求“一次写作,在任何地方运行”。不同的平台具有不同的外观,感觉和功能,因此我们仍然应该为每个平台开发离散应用程序,但是同样的工程师应该能够为任何选择的平台构建应用程序,而无需为每个平台学习一套不同的技术。 我们称之为“学习一次,写在任何地方”。

所以这意味着当你想要针对每个平台优化UI时,共享UI平台(如Xamarin.Forms)已经在窗口之外。这反过来意味着近100%的代码共享成为一个无法达到的目标。根据你的应用程序的性质,假定在平台上共享60%的代码。

网络再次与移动平台完全不同,至少是在笔记本电脑或桌面上使用时。屏幕大小很重要,键盘的存在也是如此,使用鼠标与触摸屏时的交互也是如此。一旦了解了性能,你将看到基于Web的解决方案的好处并不多,除非你在网络技术方面非常有经验,绝对不想学习新的语言。 请注意,平台的差异不仅限于你的应用程序的可视化方面。它包括在每个操作系统上存在,丢失或不同的所有功能。 Android开发人员可以使用大量功能,这些功能在iOS上是不可能的。想想Android的丰富的通知,开放蓝牙接入,NFC和USB通信,永远在线视图,即时应用程序,启动屏幕小部件,或许更多。 iOS反之亦然:智能应用横幅,专用加密硬件,3D触摸。其他的不同之处在于跨平台的包装器是统一的:画中画,ARKit与ARCore,播放音乐的机制,以及应用在后台执行任务的时间和时间,何时以及如何请求权限,访问外部存储...

感谢Google的高级软件工程师Romain Guy解决了我们的部分担忧。

2.性能

比本地程序更快是不可能的。 本地跨平台代码被翻译成字节码或本地机器码,因此理论上可以实现原生性能,但是经常会有各种各样的局限。 例如,Xamarin向每个应用程序发送一个导致一些开销的功能库,这对于动画的平滑性或对用户交互的响应可能并不重要,但它在启动时间,内存使用和应用程序大小方面都很重要。 Xamarin内置的一个简单的“hello world”应用程序可以占用惊人的16Mb(比Instant App的最大尺寸大4倍)。

以毫秒为单位加载和保存图片; 越低越好。 从2017年8月统计

以毫秒为单位加载和保存图片; 越低越好。 统计从2017年8月

基于网络的方法的性能甚至没有降低太多。传统上在移动浏览器或网络视图中运行的网站对于性能来说是不利的,但是在多年来已经有了很大的改进,响应能力的差异不仅是可测量的,而且也非常显着。一个简单而精心制作的基于Web的应用程序可能会欺骗用户认为它是本地的,但是无论如何,动画像其UI组件一样平滑,屏幕转换或设备旋转都会让你失望。这是Facebook发明了React的主要原因。

“不幸的是,由于所有渲染都是使用Web技术完成的,所以我们无法产生真正的本地用户体验。” -by Facebook

3.易于扩展性

对于我来说,这是一个个人的抱负,因为我在创建Xamarin应用程序时遇到了很多麻烦。这些工具一直很麻烦,开发过程很麻烦,所以我必须尽力保持不要对Xamarin造成不利影响。

4.错误

Android和iOS是坚实的平台,但即使存在一些bug。在操作系统,开发工具和使用的库中存在错误或意外或未记录的行为。在开发过程中添加另一层软件,你将添加更多错误。在Xamarin的中,这个列表是很长的。在我们的办公室有一个名为“Xamarin Sh * t的大清单”的共享文件。它不仅仅处理更多的问题,而且还增加了工具链的复杂性,从而导致了更复杂的调试过程。

5.工具的不成熟

跨平台工具链比本机平台不成熟的事实并不仅仅是导致更多的错误发生。这也意味着它们不完整。想想XCode和Android Lint执行的自动化代码检查,它会在开发过程中警告错误和安全问题。想想IDE的帮助和加快编写代码,有助于跟踪错误,跟踪性能问题(内存,CPU,gpu,电池使用情况等)。虽然其他平台当然也会发布自己的类似工具,但本地平台已经存在了多年。

高级Java IDE

6.新平台功能的缓慢整合

XCode和Android Studio(基于IntelliJ)经过测试,始终是第一个发布新功能的,并保证可以访问开发人员可用的100%的平台功能。由于固有性质,跨平台工具将始终在每一次更新的曲线后面。可以肯定的是,Xamarin一直很快采用,他们甚至大胆地声称要花几个小时来包括新的操作系统功能,但问题是很多的。有时候,Appstore强制应用程序为64位CPU构建,而Xamarin尚不稳定。

7.编程语言

哪些编程语言被认为是“好”,哪些是“坏”的。每种语言都有自己的优点和缺点。但是,尽管如此,个人意见在这个讨论中起着重要的作用,但一些语言本身比其他语言更安全。无论你的codestyle-check还是IDE有多好,只能使用一种语言而不是另一种语言避免某些错误。 Javascript(由React使用)允许你使用解释器无法打印的拼写错误,导致运行时错误,而不是拼写检查器类似的警告。

javascript

8.库的可用性

流行的跨平台解决方案通常有一个良好的包管理器,可以提供各种各样的插件或库。例如,Xamarin的NuGet存储库具有惊人的大量插件,并且包括许多流行的本机库。这些存储库中没有一个与可用于本地平台的库的数量进行比较。你经常可以移植现有的本机库,不好的事情是你经常需要这样做。而对于某些跨平台技术,这意味着你将需要了解本机编程语言,这是你在选择跨平台语言时所要避免的。

9.缓慢的编码和运行周期

诚然,这个论点有两个方面。有基于Web和本地的跨平台选项,可以很快地显示代码更改,还有一些平台,每次你做一个小的改进时候,都需要部署到设备或模拟器上更改。

10.白标签

当你为不同的客户端部署不同品牌的应用程序时,这一点很重要。 Android上的“构建版本”或iOS上的“目标” - 这些平台具有简单的系统来支持这一点。我所知道的跨平台方法并不支持这一点,所以你将在构建过程中最终编写自己的解决方案并使每个部署更加复杂。

11.专业知识

个人擅长是一个主观的事情。如果你在Ruby中有丰富经验,那么你可能最喜欢在Rhomobile中创建移动应用。如果你在过去30年里一直在Basic编程,你可以坚持你所知道和使用B4X。 Pixplicity的开发人员拥有多年的本地技术经验,我们长期以来一直在高水平编程,并经常在我们的Android学院和世界各地的会议上教授我们的知识。这会影响你在选择技术开发应用程序时的选择,但应该如何?

12.学习一种新语言

但这是简单的吗?如果你想编写一个高质量的应用程序,你需要知道你正在定位的平台。你需要知道平台可以做什么和不能做什么,他们的SDK提供什么,甚至你需要考虑哪些错误或特性。对于每个平台通常甚至每个平台的每个版本。很容易估计你仍然需要学习的知识数量,远超已经知道的知识。如果你是有经验的C#开发人员,那么关于.Net和GDI的所有知识都是无用的。实际上,学习编程语言是应用程序开发的容易部分。这是从C#到Java或从Swift到Kotlin的一小步。如果你理解这个概念,语法是微不足道的。

13.多年的经验

当然,像Ruby,C#或JavaScript这样的跨平台语言已经存在了,但这些平台还没有。 React Native于2015年3月发布。在撰写本文时,根本无法找到超过2.5年经验的React Native开发人员。

14.文档

任何体面的跨平台解决方案都有很好的记录。本土发展记录更好。他们有一个更大的在线社区。他们有更多的会议和更多的本地会议。在Stack Overflow上,Android + Java上有191,918个积极的问题,iOS + Swift上的103,641个,React的59,355个,Cordova的54,126个,Xamarin的25,976个。当然这表明社区规模和参与度,而不是本地程序设计是难于使用的。

15.业务依赖性

所以现在你知道我非常不喜欢跨平台的开发,希望现在也可以这样做。但到目前为止,我甚至只涵盖了应用程序开发的实践方面。我们来看看未来,看看它会如何影响你的业务。 苹果和谷歌有巨大的团队建立他们的平台,只要这些平台存在,他们就会有这样的一面。这是你可以获得的最佳保证,即对他们提供的工具的长期支持,以及其积极的持续发展。本地平台的普及也为社区周围的社区提供了更大的支持,并且有更多稳定的经验丰富的程序员供应。 然而,跨平台工具完全依赖于为其资助的公司的议程。他们都没有对支持和未来计划提供任何保证。没有保证他们将与下一次更新的Android或iOS兼容,不能保证他们下个月甚至会存在。如果发生这种情况,你只能希望这项技术将被移交给社区,并将继续作为开源,毫无疑问,发展速度将会慢得多。 “该公司没有提供任何保证,它不会拉插入项目 。”

Ariel Elkon关于React Native的评论。 如果过去是未来的任何迹象,那么当今流行的跨平台解决方案将在大约两年的时间内被取代。 Titanium,PhoneGap和Adobe AIR都被视为跨平台开发中的下一个重要任务。现在是React和Xamarin代替;先进的Web应用程序可能在未来接替他们。

注意

那么什么时候应该使用一些跨平台的工具包呢? 有两个很大的例外:

游戏 -

游戏通常不依赖于本机组件。 他们正在使用自定义UI组件,这些UI组件旨在适应游戏的外观和风格,因此无需编写本机布局。 无论是2D还是3D,游戏通常都是建立在OpenGL之上的,其中性能非常好,视觉逻辑构成了应用程序的很大一部分,可以跨平台共享。 如果你正在做一个游戏,那么是的,你应该使用像Unity或Unreal这样的东西。

快速原型

如果你很快想要测试一个想法并将其部署到一组测试人员,那么你可能对应用程序的交互方式更感兴趣,而不是它是否具有良好的性能。 根据你的专业知识,跨平台工具集可以非常适合以快速简便的方式创建原型。

TL; DR

你承诺了60%至90%的共享代码,从而实现更快的开发和更少的维护。但由于工具不足,开发过程已经放缓,开发人员不高兴,由于缺少库,手工制作更多的组件,每一个软件更新都会开始破解。部署时间更长。测试不足,所以有更多的错误。现在,你将开发成本削减了20%,而不是预期的60-90%,除此之外,你的用户还会留下不良评级。 我们已经看到它发生了,我们会继续看到它发生。没有人说这也会发生在你身上,但是在选择平台时请考虑这篇文章。客户通过一个跨平台的应用程序来找我们,要求使用本地技术重建它。没有一次是相反的。

国内某高校图书馆

关于作者

Mathijs Lagerberg在建立了几个Android应用程序后,于2012年初共同创立了Pixplicity。 Android OS在这些时代还很年轻,只有很小的市场份额。在无数的语言中编程好几年的生活,将这个新技术潜入头脑,加入一个专注于构建移动应用的初创企业是有道理的。随着时间的推移,Pixplicity已经发展成为一个有创意的技术机构,有幸玩过所有有趣的双字母缩写:A.R.,V.R.和A.I ..仍然在构建应用程序,但不是跨平台的。