写点什么

我为什么放弃移动开发

  • 2020-06-22
  • 本文字数:3480 字

    阅读完需:约 11 分钟

我为什么放弃移动开发

当我还在上大学的时候,Android 和 iOS 还是新兴的平台,每个人都对这两项技术很感兴趣。如果你参加一些当时的编程研讨会,最后总会写一个小型的 Android 应用。这就是我向 Android 生态系统迈出的第一步,也可能是我随后成为了一名移动开发者的原因。


在这篇文章中,我想要分享我关于 Android SDK 和 Flutter 的糟糕体验。我提到的某些要点也适用于 iOS SDK。我已经在几年前放弃了移动开发的工作,希望后来许多事情已经在朝好的方向改进。但在当时,我发现移动生态系统是如此的令人感到困惑和挫败,以至于我选择了一条不同的职业路径。


本文由原作者发表在 medium.com,经原作者授权由 InfoQ 中文站翻译并分享


设备的碎片化

对开发者而言,Android 开发的最大痛点,就是设备配置的巨大差异。我一直都未能理解为什么 SDK 中大部分功能(尤其是用户交互界面的部分)取决于设备,而不是我的应用。这从根本上导致我必须使用支持库,针对每个目标 API 级别调试我的应用。除此之外,我还经常遇到在仿真器或者测试设备上好好的代码,却在某个三星或者华为的设备上崩溃的情况。

质感设计(Material Design)

当我在 HackerNews 或者 Reddit 上读到关于谷歌的 Material Design 的评论时,某些时刻会感到我是唯一真正喜欢它的人。我觉得它在视觉上很具吸引力,我通常很享受这样的用户体验。官方的文档网站发展得很快,也非常成功,我觉得这是优秀文档的典范。当它被宣布用于 Android 时,我感到非常兴奋!


话虽如此,在 Android 平台上从 Holo 过渡到 Material Design 并非一帆风顺。因为它好像是被急匆匆发布出来似的。在接下来的几年之中,官方的 Material Design 支持库一直缺少一些非常基本的组件。虽然你有时可以在谷歌自有的应用上看到这些组件,但是它们并没有真正被纳入到支持库中。开发者不得不构建自己的组件,或者使用 GitHub 上质量无法保证的实现作为替代品。这次使用 Material Design 支持库的经历,再加上大量的不一致的视觉设计和实现错误,让我第一次停下来真正地思考和质疑这个生态系统。


无人理会的最佳实践

构建一个可靠的 Android 应用,是一项充满挑战的任务。这主要是因为 SDK 对开发者并不友好。理论上,一个 Android 应用程序可以永远挂在后台不使用任何系统资源,然后在用户需要时立即回到先前的状态,这实在是令人惊讶。不过前提是开发者正确地实现了这个应用的状态和生命周期管理机制。


开发者:你好,互联网!我的应用在改变屏幕方向时崩溃了,该如何解决?

互联网:这很简单!禁止改变屏幕方向即可。


——啊哦,不幸的是,这种回复很普遍。


你是否曾经使用过 Java 中的线程(Threads)?在可变变量随处可见的的命令式代码库中,这件事变得非常困难。但你猜怎么着?在 Android SDK 中使用线程更加困难。如果你想要在一个 Activity 中管理 Thread,那你就只能自求多福了。幸运的是,我们最终保留了 Fragments,这最终让这件事变得容易了一些。但代价是在一开始就需要使用 Fragments。


在我作为一名移动开发者的职业生涯中,我面试了一些高级 Android 开发者。他们几乎无一例外,都很难给出这些话题的正确答案。


我一直希望谷歌能更坦然地承认这些问题,并且和社区一起解决。这些问题可能随着 Kotlin 的发布有所改善,但 Android 生态系统的根基仍然存在很多潜在的问题。

无效的设计模式和对抽象的注解(Annotation)

开发者很快就意识到,在 Android SDK 提供的抽象之上,构建一个真实世界的应用是不可能的。对此的解决方案是层出不穷的设计模式,甚至每周可能都会出现新的设计模式,我记得的包括:MVC、MVP、MVVM 和 MVI。而且由于无法使用普通的构造函数调用来管理依赖项,我们不得不在代码库的每个地方使用注解。这些本来并没有必要。Java,甚至 Kotlin,本来就有足够的能力可以对这些东西建模,更何况是以一种透明而直接的方式。但 Android 更喜欢 XML 定义和反射式实例化,因此开发者不得不在代码中使用注解和各种设计模式。实话实说,我真的无法形容这到底有多麻烦。

从未利用过的平台优势

在某种程度上,原生 iOS 和 Android 开发都是作为平台在与网页端竞争。但 iOS 和 Android 拥有只属于一家企业的巨大的平台优势,相比之下,网页端有许多利益相关者,这些利益相关者都想要根据他们的需要来影响网页端的开发。


然而,网页端拥有更加活跃和创新的生态系统。只需要想想 React 的成功故事:基于组件的用户界面,是我们目前提出的最简洁的抽象方法,这是无可否认的。多年以来,Android 并不理会这一趋势,直到最近才宣布推出“Jetpack Compose”,但是这仍然仅支持在开发者预览模式下使用。同样的事情也出现在 iOS 开发中。


所以,现状是我们仍然需要继承 android.view.View 类,这个类有 1.5 万行代码,和数十个生命周期函数,但同时我们还要尝试注入自己的 merge XML 文件。iOS 和 Android 本来可以成为这个竞争中的引领者,但实际上,它们已经被远远甩在了后面。

请不要对 UI 开发抱以希望

一个精美的应用的关键在于用户界面(UI)。我在上文已经吐槽了不少关于组件的问题,但这些还不是最严重的。你是否曾经调试过网站上的故障?通常的操作是:打开浏览器的开发工具,点击有问题的元素,然后使用 CSS 和 HTML 的属性来调试。与此相比,Android 是一个无法访问的黑盒。老实说,我一直没有完全理解 Android 的主题和样式机制,并且与 Web 相比,Android 的工具显得毫无用处。


想要在这个框周围添加阴影吗?没问题,请使用这个奇怪的.9.png 文件,或者依靠 API Level 21,你就可以正确渲染阴影了(尽管只有凸形阴影)。

不好意思,你忘记实现自定义视图四个构造函数的其中一个了。但我不会抛出编译错误,我只会在运行时崩溃!

现在有支持超高屏幕密度的手机了。可以在应用里添加 xxxhpi 的 assets 吗?不行,不支持矢量图,我们做不了这个。

——来自 Android SDK 的深夜独白

矢量图

在 Android 21(5.0)之前,Android 平台根本不支持正确的矢量图。这背后的原因是,多样的 Android 设备导致了多种不同的屏幕密度,这要求图像针对每种屏幕密度都做仔细的调整。务实的开发者自然而然地开发了转换矢量图的工具,将 logo.svg 转换成 ldpi/logo.png,mdpi/logo.png,hdpi/logo.png,xhdpi/logo.png,xxhdpi/logo.png 以及 xxxhdpi/logo.png。幸运的是,最终谷歌改变了它们的想法,并提供了 VectorDrawble 来支持部分可缩放矢量图形(SVG)。的确,这足够减轻当时的痛苦。但仍然令我困惑的是,一个以能够在任何设备配置上运行为优势的开发环境,是如何在这么长时间都不支持矢量图的情况下活下来的?

死局

这些年,我开始越来越担心我的知识会在不远的将来过时。我学到的大多数知识都是 Android 开发所特有的,很少适用于更广泛的软件开发领域。考虑到这些方面,我不认为原生的移动开发会一直存在,所以我开始担心所学到的技能的实用性。

Flutter

当 Flutter 发布时,我非常激动。它承诺将解决一些主要的 Android SDK 的缺陷,同时无偿提供跨平台支持。所以在我上一份工作中,我们开始从原生 Android 迁移到 Flutter 上。我必须承认,Flutter 信守了它的承诺:


  • Flutter 内置的渲染流水线完全解决了 Android 的碎片化问题。

  • 从一开始,它就提供了详尽的高质量的 Material Design 组件库。

  • 热重载功能的灵活性完全颠覆了我的认知。

  • 你能获得前所未有的高质量界面外观的跨平台体验。


但不幸的是,它也不完美。而且有点可惜的是,Flutter 遇到的问题本可以通过一个全新的项目轻松避免。


  • Dart 很糟糕:它还是一门相对年轻的语言,但它重蹈了不少它的前辈的覆辙(错误的类型系统,Null,使用语句而不是表达式,等等)。

  • Flutter SDK 中让人不解的设计决策:它们本应创造一个更好的 React,但却创造了一个更糟糕的。本可以通过简单的函数调用解决的问题,往往需要通过有状态的面向对象编程(OOP)机制才能解决。(我记得对话框的路由和处理在这个方面尤为痛苦)

结论

在某一时刻,我清楚的意识到,我不想在这种技术上倾注心血了。我向自己许诺,绝不再在移动平台上编程。一个设计精美的、响应式的网站在今天已经可以给你足够好的体验,所以这是我的不二之选。只需要一个代码库,它就能适用于每个客户端。如果我还是不得不构建一个移动应用程序,我仍然会选择 Flutter,甚至是在我仅针对 Android 的情况下。我绝对不会再使用 Android SDK。


话虽如此,但要澄清一点,我还是非常喜爱和欣赏精心制作的原生应用的(无论是在移动设备上还是桌面上)。我对那些使用现有工具就能创建出这样的应用的开发者,致以崇高的敬意。只是,我不想再成为他们中的一员。


原文链接:


9 reasons why I gave up on being a Mobile Developer


2020-06-22 10:0010636

评论 5 条评论

发布
用户头像
已转行
2020-07-21 15:43
回复
用户头像
做了6年的android工程师,从个人的经历来讲,好的移动开发要适应项目,甚至是公司。例如我在上一家产品研发型公司,我能把app页面流畅度做到秒开,内存做到实时的回收等,但是现在这一家产品+项目性公司,甲方的要求就是坨屎也得跟他实现的情况,抱歉,牺牲是在所难免的。但是大家都高兴了(当然我是希望能够做的更好一些)。
2020-06-30 22:30
回复
用户头像
作者的含义是用H5比较好?看下 www.appkuang.com
2020-06-28 09:47
回复
用户头像
“老实说,我一直没有完全理解 Android 的主题和样式机制”--同感
2020-06-26 21:14
回复
用户头像
有道理的。
2020-06-24 10:19
回复
没有更多了
发现更多内容

淘宝杨宽:淘宝直播低延迟架构演进和实践丨ECUG Meetup 回顾

七牛云

音视频 淘宝 ECUG 七牛云

当 CloudQuery 遇到大数据

BinTools图尔兹

大数据 hive ES 数据库管理

oeasy教您玩转vim - 12 - # 词头词尾

o

破解三大安防视频痛点,看华为4大硬核视频上云技术

华为云开发者联盟

视频 华为云视频 安防 摄像头 安防视频

Druid 加载 Kafka 流数据 Supervisor 配置

HoneyMoose

WeLink的杀手锏和远程办公软件的另一面

华为云开发者联盟

远程办公 华为云 welink 视频会议 数字化办公

Python代码阅读(第8篇):列表元素逻辑判断

Felix

Python 编程 Code Programing 阅读代码

百度大脑DuMix AR携明星数字员工首次亮相China Joy,智能虚拟形象系统全面升级

百度大脑

人工智能 ChinaJoy 虚拟偶像 数字人

【LeetCode】0~n-1中缺失的数字Java题解

Albert

算法 LeetCode 8月日更

书单 | 振聋发聩,撼世经典!总有那么一些书经得住时间的考验

博文视点Broadview

netty系列之:基于流的数据传输

程序那些事

Java Netty nio 程序那些事

Prometheus 监控SpringCloud微服务

Rubble

Prometheus SpringCloud 8月日更

带你了解Go怎样实现二级缓存

Regan Yue

redis 二级缓存 Go 语言 8月日更

网络攻击的高频出现,高防服务器是最佳的选择

九河云安全

docker入门:单机elasticsearch安装记录,保证无坑

小鲍侃java

8月日更

同为电动小车热门,欧拉白猫比拼零跑T03,谁更胜一筹?

科技热闻

探究Presto SQL引擎(1)-巧用Antlr

vivo互联网技术

sql 编译器 presto antlr4

Vue进阶(二十一):ES6 知识储备

No Silver Bullet

Vue ES6 8月日更

Vue进阶(二十三):Promise 详解

No Silver Bullet

Vue Promise 异步请求 8月日更

【Vue2.x 源码学习】第三十一篇 - diff算法-比对优化(下)

Brave

源码 vue2 8月日更

手撸二叉树之最小深度

HelloWorld杰少

数据结构与算法 8月日更

十大排序算法--基数排序

Ayue、

排序算法 8月日更

“互联网+”大赛之AI创新应用赛题攻略:大胆脑洞,共绘智慧生活蓝图

华为云开发者联盟

AI HarmonyOS 大赛 互联网+ HMS Core

索信达控股:打造新一代中小银行智能营销平台体系的道与术

索信达控股

四色建模:用户转化率 KPI

escray

学习 极客时间 如何落地业务建模 8月日更 四色建模

【Flutter 专题】71 图解基本隐式动画 Widget

阿策小和尚

Flutter 小菜 0 基础学习 Flutter Android 小菜鸟 8月日更

BERT模型为什么这么强?

博文视点Broadview

Apache APISIX 在移动云的应用

API7.ai 技术团队

开源 网关 APISIX

生产环境全链路压测平台Takin

TakinTalks稳定性社区

开源 高可用 全链路压测 性能压测

百度BaikalDB在同程艺龙的成功应用实践剖析

百度Geek说

数据库 架构 后端

从0开始的TypeScriptの三:TS的类型

空城机

typescript 大前端 8月日更

我为什么放弃移动开发_移动_Niklas Klein_InfoQ精选文章