去年这个时候,我发表了一篇文章,内容是我对 React Native 的印象,它在 2016 年和 2017 年风靡一时,Facebook,Instagram,Tesla,Walmart,Airbnb,Skype 等公司开始调研使用,并推出基于 RN 的业务的应用或在应用中部分页面使用 RN。
但是今年,React Native 似乎正在失去它的市场吸引力,一些著名的公司已经宣布放弃它(比如 Airbnb 和 Udacity)。 通过与开发人员交流中,发布的文章中,或者在 LinkedIn 上招聘 JD进行判断,看起来它不再那么火爆了。 但要明确的是,它并没有被遗弃,只是相对来说它对一些公司来说由于不适合而不在被使用,但是并不意味着它不适用于其他公司。 许多这些公司在其应用程序的子页面而不是所有应用程序的子页面上使用它,可能使用它如此复杂的原因之一。然而,我们不能否认,如果有助于推广技术而做出贡献的大公司(通过基于该技术创建的流行的开源库)团队一旦最终决定弃用它,它会对社区产生影响。但是这样至少能帮助以前对使用它持观望态度的团队可以更容易地做出决定,使用上面这样的例子来支持他们的是否投入。
2017 年有了些新的改变。 在 Google IO 开发者大会上,谷歌公开发布了自己的移动应用跨平台技术早期 alpha 版本的 Flutter。 今年的会议中,谷歌宣布 Flutter 已经准备好投入生产,并在已经在 9月底推出了 Release Preview 2。(译者注:本周已发布了 1.0 正式版)。官方提出了 Flutter 带来的亮点:
1. 最新版本的主题是像素完美的 iOS 应用程序(虽然以前主要集中的是 Android 的材质设计上)。
2. 注意,这款应用缩小了安装包的大小,在发布模式下,最小的 Android 应用现在只有4.7MB。
3. Flutter 从一开始就是开源的,它进入了 GitHub 上最活跃的 50 个 repo(仓库) 中。
4. 一些大公司正在使用它,例如阿里巴巴(Android, iOS)、腾讯(Android, iOS)和谷歌广告(Android, iOS)。阿里巴巴的闲鱼就是基于 Flutter 开发的,并且在中国有5000多万用户在使用该应用。
5. 此图表显示了 Flutter 如何在Stack Overflow上获得大量关注势头:
因此,这足够激起了我的兴趣去学习它,了解它的全部内容,并使用它创建一个真正的应用程序(因为,技术这种事仅靠阅读文档是不足以获得一些对新东西的真正掌握程度的)。
1. Flutter 是由谷歌开发的一个开源软件开发工具包(SDK),可以快速构建 iOS 端和 Android 端应用程序,两个平台共享大部分代码。它与 Android 和 iOS sdk 协同工作,这也意味着您仍然需要一台 macOS 机器来为 iOS 构建(就像您为 React Native 和 Xamarin 所做的那样)。
2. 它使用 Dart 编程语言构建程序,也是由 Google 开发的。 是的,需要学习一门新的语言,但不要担心,如果你熟悉Java,JS,Kotlin,Swift 或 C#,这是非常容易的。
3. 该应用程序会提前编译为本机 ARM 代码,而不是像 React Native 中那样在运行时编译。 这样可以提供更好的性能,因为中间 没有 JS bridge 来解析和执行代码。 但是,这也意味着通过在运行时下载新的 JS 代码包,没有无线更新选项。
4. 它不是在 iOS / Android 特定的原生 UI 组件(这就是React Native和Xamarin所做的)之上的包装器,而是通过一个 Skia 这个 C ++ 2D 图形库,快速的在「屏幕画布」上从头开始绘制UI。 Skia(也可作为谷歌 Chrome,Chrome OS,Android,Mozilla Firefox 和 Firefox OS 以及许多其他产品的图形引擎)。Skia 项目开始于 1996 年,2005 年被谷歌收购,尽管它是在 BSD 许可下发布的,任何人都可以使用它。这将产生巨大的影响,我将在下面的利与弊部分详细讨论这个问题。
5. 与 React Native 类似,Flutter 也基于「单向数据流」架构或反应式编程。更简单的是,应用程序通过更改变量或者属性(或者更新屏幕或视图的「状态」)来响应用户输入,并根据新状态重新渲染 UI。函数不会直接更改 UI (按钮的颜色、标签的文本、列表的内容等)。
6. 再次,与 React Native 类似,有热更新。 您只需在代码编辑器中更改内容,保存,并在 Android emu 或 iOS sim 上刷新 UI。 这是非常方便和快速的,一旦你尝试它就很难不去使用它,它弥补了 UI 是以编程方式创建的,因此没有可视化编辑器。
7. Flutter 可通过第三方插件进行扩展,这些插件可添加新的自定义 UI 组件或包含内置类尚未涵盖的平台特定功能(例如:用于视频/音频,货币化,存储,相机,增强现实,机器学习等等)。
8. 与 7 相关联,Flutter 通过在检查 Platform.isIOS 和 Platform.isAndroid 之后执行不同的代码来编写特定于平台的代码变得相对容易(用于如果要在实例化的 UI 小部件中存在差异,或者 dart 文件存在逻辑差异),或者通过编写自己的原生插件(如果你真的需要包含 Flutter 尚未提供的特定于平台的功能)。
9. 依旧与 7 相关联,性能应该不是典型应用程序的问题(至少在发布模式下 - 调试模式明显更慢,因为它使用虚拟机来运行 Dart 代码),因为 UI 是由快速低级写入的 C++ lib 和其他功能映射到它们的原生部分。 但是,您必须通过最小化重绘次数并仅重绘状态改变需要重绘的部分正确执行此操作。
10. 你可以使用任何文本编辑器和 flutter 命令来编写和构建应用程序,但推荐的方法是使用支持 Flutter 插件的编辑器之一,即 Android Studio,VS Code 或 Intelli J。这能给你更佳的编程体验,您同时需要使用命令行来编译和运行应用程序。
1. Flutter 自己绘制 UI,而不是包装特定于平台的原生组件,这一事实既有优点也有缺点。优点是如果某样东西在你的 iOS 12 测试 iPhone 上以某种方式呈现,那么它以完全相同的方式呈现,不仅是在任何其他 iOS 版本上,而且在任何安卓手机上也是如此。而使用 React Native 或 Xamarin, UI 组件有许多属性只在一个平台或另一个平台上受支持,或者它们虽然都支持,但在后台以略微不同的方式被转换为它们的本地对应组件。这意味着您需要在许多设备和操作系统版本上进行测试(并且可能会编写特定于平台的代码来修复某些情况),或者只是知道某些用户看起来可能会不同甚至影响功能。 如果您使用特定操作系统版本不支持的属性或功能,您的应用甚至可能会崩溃。而使用 Flutter,您将更加安全(至少对于应用程序的 UI 部分是这样)。 您仍需检查多个设备上的应用程序,尤其是在使用涉及到底层代码的第三方插件时。 如果您使用音频/视频,推送通知,应用内结算等内容,就会出现这种情况。这种方法的消极方面将在本文的下一部分中介绍。
2. 热更新非常有用,它完成了开发人员的梦想:编辑器中的保存,以及应用程序在 SIM 卡上重新加载! 不用再去等待无尽的构建然后等待,运行然后等待再测试然后重启的无尽的过程。 实际上,当您更改资源和插件,更改导航中的某些内容,状态初始化或逻辑时,仍需要重建,但大多数 UI 更改会在应用程序运行时立即应用。 对于 UI 复杂的应用程序,这是很浪费时间的地方。
3. 我喜欢小型可复用组件的整体远离,它们会对「状态」的变化作出反应来更新,这也是 React 和 React Native 的核心思想之一。 当然,反应型的应用程序也可以在纯 iOS 和 Android 开发中开发,但使用 Flutter(和 RN )更容易,更自然。 这是因为它是核心,而不是由第三方库提供并以多种不同方式实现的东西。
4. Dart 虽然简单但是功能强大且完整,与 Swift,Kotlin 或 Java 相当。 使用 async / await / Future 进行异步编程是轻而易举的,它也感觉完整且一致。
5. Flutter 和 Dart 内置支持逻辑单元测试和 UI /交互的小部件测试。例如,您可以发送点击和滚动手势,在窗口小部件树中查找子窗口小部件,读取文本,并验证窗口小部件属性的值是否正确。 官方文档很好地清楚地展示了可用的内容。
6. 我喜欢自带的主题颜色支持的每一个方面的应用程序的 UI。在创建我的应用程序的明暗主题时,最困难的部分实际上是选择正确的颜色(我只创建了两种颜色,但用同样的方法也可以创建10种)。就代码而言,它只有几行。
优点:这是任何跨平台技术在现实中都应具有的优势,不仅仅是 Flutter,我还想提一下:为两个平台同时创建一个应用程序可以让它们更容易保持一致。在传统的开发过程中,您可能需要同时启动这两个平台,并且具有相同的特性,但是不久之后您就会意识到一个平台的性能优于另一个平台(就下载、销售、广告收入而言)。然后你开始削减另一方面的成本,这意味着其中一个部分落后了。
我不得不说我并没有真正找到任何值得留在「坏」或「丑陋」部分的东西,但这里有一些不太好的东西,至少从某些观点来看:
1. 正如已经提到过的几次,Flutter 以自己的自定义方式来绘制 UI,它不会使用原生组件。 它只是在复制 Android 的 Material Design 以及使用 Cupertino 库的 iOS 特定组件方面表现非常出色,但它仍然不是原生的。 这有一些含义,例如:
(a) 如果 iOS 13 改变了分段控件或 UISwitch 的渲染方式,那么使用 CupertinoSegmentedControl 或 CupertinoSwitch 的 Flutter 应用程序将保持旧的外观,直到 Flutter 更新并重新构建程序。 有人可能会争辩说很多用户都不在乎(至少我的大多数非技术朋友都不关心,甚至不会注意到,例如,他们只关心应用程序看起来足够漂亮而不是 100% 与操作系统的外观和感觉一致),但如果你是一个强迫症或者追求纯粹,它可能会会带来不好的体验。
(b) 如果您计划仅将 Flutter 用于你现有应用程序的一部分,您可能会看到和原生部分之间存在差异和抖动的部分。同样,这可能会困扰你(和你的用户)。 但是对于 100% 的新应用程序来说,问题当然少了很多。
(c) 为了让您作为开发人员觉得尽可能简单,并假设您的用户不关心应用程序的原生外观,您可以使用 MaterialApp (使用Material Design组件)并为 Android 和 iOS 编译它 。 它会工作正常,尽管非原生外观,它实际上是我为我的应用程序做的。 相反,如果您确实关心这一点,并决定使用 MaterialApp for Android 和 CupertinoApp for iOS,那么您将复制大部分(如果不是所有) UI 代码(这可能是您应用的相当一部分),并且你将使架构更复杂。 仔细考虑这一点并确定它是否值得。
2. Flutter 没有像 React Native 甚至 Xamarin 那样丰富的插件。 这可能只是因为 Flutter 更新迭代,而且目前社区规模更小,但事实情况就是如此。 选择是有限的,许多插件都是旧的,没有维护,甚至可能甚至不适用使用当前的 Dart / Flutter 版本。 一些组件(特别是非 UI 组件,映射特定于平台的功能)仅适用于 iOS 或 Android,但不适用于两者(通常它们支持Android,因为此时 Android 开发人员更多的是 Flutter 而不是 iOS 开发者,因为 Flutter 是来自谷歌的产物)。 然而,填补空白并为缺失的平台编写特定于平台的代码仍然比从头开始更好,并且如果 Flutter 越来越受欢迎,情况肯定会有所改善。
3. 调试(debug)不是最好的。 您可以使用 print / debugPrint 语句,查看日志,并使用工具来分析 CPU /内存或可视化视图层次结构,但与使用 Xcode 或 Android Studio 中的操作相比,我们仿佛处于不同的星球上。但是您可以使用断点,单步执行代码并检查变量值,就像使用Java / Kotlin Android 一样。这适用于 Android Studio 和 VSCode。
4. 当出现布局错误(或其他较低级别的)时,您获得的错误在屏幕或日志可能会非常混乱和模糊,因为它指向框架的某些代码行,可能是您直接与下面的许多底层级别的互动。 在原生 iOS 和 Android 上,错误通常更容易理解,如果没有,您通常只需在 Google 上复制并粘贴完整错误,并有理由相信您会获得一个有用的链接列表,告诉您更多信息。 但是对于 Flutter 来说,社区仍然相对较小,而不是那么多的问题得到解答。
5. 以编码方式(在屏幕代码所在的.dart文件中)创建 UI 非常简单直接。这也意味着没有多少分离。 但我更喜欢在单独的文件中创建带有标记代码的 UI(类似于在原生Android应用程序中执行的操作)。
6. 在 Android 上,绝大多数开发人员使用 Clean Architecture 和 MVP思想。 在 iOS 上,它可以是 MVC,MVVM Viper 等思想。 在这两种情况下(但对于 Android 来说甚至更多),有明确且众所周知的架构模式已被证明适用于大型应用程序。 但对于 Flutter (以及 React Native ),感觉它们仍然在初期探索的阶段,没有「标准」或「几乎普遍接受」的架构方法。 所有文章都只是显示简单的例子,这是正常的,因为在谈论更高级的方面之前,他们仍然需要去了解。 但是,如果您打算将 Flutter 用于相当大的项目前,那么你最好清楚地了解如何构建它,以便随着应用程序的大小和复杂性的逐渐增加,可以更好的扩展并且易于维护。同样,我绝对不是说 Flutter 不允许你构建具有干净和可维护架构的应用程序,而只是会涉及一些调研和试错的阶段,因为它不是那么成熟和广泛使用的东西。正如我们在原生 iOS / Android 应用程序中习惯的那样。
总结一下:Flutter 有很多潜力,它很容易上手,实际上动手去做一些东西,并且有许多好的原则和想法。 然而,社区仍然很小,跨平台插件缺少积累,或者在当下的情况下没有太多选择。 此外,你必须接受没有 100% 具有原生系统外观的 UI 这一事实,如果你想要至少尽可能接近 iOS 和 Android,你的代码和结构将获得更多复杂。
就个人而言,我认为这是一种非常有用的技术,适用于以下情况:
最后想说的是,创建我的第一个简单的应用程序在大多数情况下非常愉快,尽管我过去开发了很多 iOS 和 Android 原生应用程序,但我确信它花了我更少的时间 在 Flutter 中创建一个应用(尽管我开始时并不了解它),而不是创建两个独立的原生应用程序。
原文链接:https://medium.com/asos-techblog/flutter-vs-react-native-for-ios-android-app-development-c41b4e038db9
更多精彩,欢迎关注公众号 3CrazyZhang