在我上大学时,Android 和 iOS 仍然是相当新的平台,让很多人为之兴奋。当举办一些编码研讨会时,几乎可以肯定会以构建一个小型 Android 应用程序来结束研讨会。这就是我在 Android 职业生涯中迈出的第一步,也是后来我成为移动开发人员的原因。
在本文中,我想分享一下我使用 Android SDK 和 Flutter 的沮丧经历。我面临的一些问题也适用于 iOS SDK。几年前,我不再从事移动开发,并希望许多事情变得更好。但即使在那时,我仍然发现移动生态系统被误导了,以至于我不得不寻找替代的职业道路。
每个 Android 开发人员面临的最大的痛点是设备配置种类繁多。我经常在思考为什么 SDK 的一些东西(尤其是UI部分)不是应用程序的依赖项,而是嵌入到设备中。这迫使我需要使用一些支持库并需要针对每个 target API调试我的应用程序。除此之外,我的代码经常在 Samsung 或 Huawei 设备上随机崩溃,而这些代码在模拟器或其它测试设备上工作得很好。
当我在 HackerNews 或 Reddit 上阅读有关 Google 的 Material Design 的评论时,有时会觉得我是唯一真正喜欢它的人。Meterial Design 在视觉上很吸引人,并且总体上用户体验很好。官方文档已经运营了很长一段时间,我认为这是出色文档的一个很好的例子。当 Meterial Design 宣布用于 Android 时,我感到非常兴奋!话虽这么说,在 Android 平台上从 Holo 过渡到 Material Design 并非一帆风顺。感觉像是为了赶着发布。接下来的几年里,官方的 Material Design 支持库中缺少了一些非常基本的小部件。即使您有时可以在 Google 自己的应用程序中看到它们,但它们并没有被添加到支持库。开发人员被迫在GitHub上构建自己的或获取质量可疑的替代实现。除了相当多的视觉不一致和实现错误外,Material Design 支持库的使用体验可能是我第一次停下来真正地思考和质疑这个生态系统。
打造坚如磐石的Android应用程序是一项艰巨的任务。这主要是因为 SDK 对开发人员并不友好。从理论上讲,一个 Android 应用程序可以无限期地在后台闲置,不占用系统资源,并在用户需要时立即恢复其先前状态。如果开发人员已经成功实现了状态和生命周期管理,则至少应该是这样。
开发人员:Hello internet,我的应用因方向更改而崩溃,该如何解决? Internet:很简单,只需禁用方向更改
不幸的是,这种情况很普遍。
您在 Java 中使用过线程吗?在命令式代码中到处都是可变变量的情况下,维护线程变得非常困难。好吧,你猜怎么着:使用 Android SDK 时这会更加困难。如果您想通过 Activity
管理线程,则基本上是在浪费时间。幸运的是,我们最终有了 Fragments,这使线程操作更加容易。但是首先需要获得 Fragments。
在我作为移动开发人员的职业生涯中,我面试了许多高级 Android 开发人员,除了极少数例外,他们都曾努力使这些线程能够正确的运行。
我一直希望 Google 能够更多地了解这些问题,并与社区合作解决这些问题。借助 Kotlin,情况可能有所改善,但 Android 生态系统的不可信的基础设施仍潜伏着不少问题。
开发人员很快会意识到,不可能在 Android SDK 提供的抽象之上构建真实的应用程序。解决方案是可能仍是一些经常被讨论的设计模式:MVC,MVP,MVVM 和 MVI。而且由于无法使用普通的构造函数调用来管理依赖项,因此我们不得不将 annotation 分散到整个代码库中。这些都没有必要。Java 甚至 Kotlin 都具有足够的表现力,可以以透明、直接的方式对所有这些事物进行建模。但是 Android 更喜欢使用庞大的 XML 定义和反射式实例化,因此开发人员必须使用 annotation 和可疑的设计模式来混淆其代码。老实说,我对这种设计无话可说。
在某种程度上,iOS 和 Android native 与 web 之间存在平台级别的竞争。iOS/Android 具有从属于独立公司的巨大优势,而 Web 则有许多利益相关者,他们都想要根据他们的需求来影响 web 的发展。然而,Web 是一个更加生动和更具创新的生态系统。只需看一下 React 的成功案例:不可否认,基于组件的用户界面方法是迄今为止我们提出的最简洁的抽象方法。Android 曾打算对这种趋势视而不见,直到最终宣布“Jetpack Compose”为止,“Jetpack Compose”仍仅在预览版中可用。iOS 几乎发生了同样的事情。因此,在这里,我们仍然从具有数十种生命周期方法的 android.view.View
类继承,同时尝试注入我们的 XML 文件。起初,iOS 和 Android 可能是真正的开拓者和推动者,但竞争却使他们完全落后。
考虑到这一点,恭喜 Android!
制作精美的应用程序的关键是用户界面。我在前文已经报怨了很多,但实际上这个主题还有更多内容。您是否曾经调试过网页上的故障?打开浏览器的开发工具,单击受影响的元素,然后修改 CSS 和 HTML 属性,直到一切正常为止。与此相比,Android是一个黑盒。老实说,我并没有彻底厌倦过 Android 的主题和样式机制,但与 Web 的可访问性相比,围绕它的工具总是显得毫无用处。
想在这个 box 周围添加阴影吗?当然,那么请使用
.9.png
文件或依靠 21+ 的 API ,您可以在其中正确渲染阴影。抱歉,您忘记在自定义视图中实现四个构造函数之一。但是我并没有因为编译错误而使您停滞不前,我宁愿在运行时崩溃!
现在有这种超高密度的屏幕。能否将各自的xxxhpi资产添加到您的应用中?不,不支持矢量图形,我们在这里不这样做。
— 在深夜使用 Android SDK 独白
在 Android 21(5.0)之前,根本不支持合适的矢量图形。这背后的原因是,Android 设备的多样性要求对图形进行仔细调整以适应每个密度级别的需求。自然地,务实的开发人员开发了一些工具来将我们的 logo.svg
转换为 ldpi/logo.png
, mdpi/logo.png
, hdpi/logo.png
, xhdpi/logo.png
, xxhdpi/logo.png
以及 xxxhdpi/logo.png
。幸运的是,Google 最终改变了主意,并引入了 VectorDrawable
,它支持 SVG
的一个子集,但向后兼容性差。当然,这足以减少之前的痛苦。但是,仍然令我感到困惑的是,这么长时间不支持矢量,这个平台为什么还能为适配任意设备而倍感自豪。
多年来,我开始越来越担心我的知识在可预见的将来会过时。我学到的大多数内容都是 Android 特有的,并且很少适用于较大的软件开发领域。考虑到平台的问题,我认为移动 native 开发不会长期存在,因此我开始担心所学技能的实用性。
发布 Flutter 时,我感到非常兴奋。它承诺将解决 Android SDK 一些主要的缺陷,同时为我们提供跨平台支持。因此,我们实际上开始将工作中的 native Android 应用迁移到 Flutter。我必须说:Flutter 兑现了承诺。
• Flutter的嵌入式渲染管线完全消除了 Android 碎片问题
• 从一开始就拥有一个详尽的高质量 Material Design 小部件库
• 热重载功能的快感让我震惊
• 您将获得前所未有的高品质外观和跨平台体验
但不幸的是,并不是一切都好。
• Dart很糟糕:它是一种相对年轻的语言,但它重复了许多其前辈的错误(糟糕的类型系统,null,语句而不是表达式等)。
• Flutter SDK中可疑的设计决策:比起 React 来,它做得更糟糕。有状态的 OOP 机制可能会解决可能只是一个简单函数调用的问题(我记得对话框小部件的路由和处理在这里特别痛苦)。
在某些时候,对我来说很明显,这不是我想与之共度的那种技术。我向自己保证不会再为移动平台编程。一个设计良好,响应迅速的网站现在可以带您走得很远,因此这是我的默认选项。这是一个单一的代码库,并且适用于每个客户端。如果绝对必须创建一个移动应用程序,即使我只针对 Android,我仍然会选择 Flutter。对我来说,使用 Android SDK 是不可能的。
话虽这么说,我必须澄清一下,我非常欣赏精心制作的 native 应用程序(在移动设备和台式机上)。我对使用可用工具创建它们的开发人员表示最大的敬意。我只是不想再成为其中之一。
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8