- 通用架构原则
- 推荐的App架构
- 搭建用户界面
- 获取数据
- 关联ViewModel和repository
- 缓存数据
- 持久化数据
- 测试
- 最终的架构
- 指导原则
- 附录暴露网络状态
本指南适用于那些已经拥有开发Android应用基础知识的开发人员,现在想了解能够开发出更加健壮、优质的应用程序架构。
注意:本指南假定读者熟悉Android框架。如果你不熟悉Android应用程序开发,请查看Android入门培训教程,其中包含本指南的必备内容。
首先需要说明的是:Android Architecture Components 翻译为 Android架构组件 并不是我自己随意翻译的,而是Google官方博客中明确称其为 Android架构组件,因此我遵循了这种叫法。
在这里我先贴上Google原文地址,以及Android架构组件官方开源示例代码地址。
Google原文地址:developer.android.google.cn/topic/libra…
Android架构组件官方开源示例代码地址(android-architecture-components): github.com/googlesampl…
下面这张图是Android架构组件完整的架构图,其中表示了的架构组件的所有模块以及它们之间如何交互:
APP开发者面临的常见问题
与传统的桌面应用程序不同,Android应用程序的结构要复杂得多,在大多数情况下,它们只在桌面快捷启动方式中有一个入口,并且作为单个进程运行。一个典型的Android应用程序是由多个 app组件(Android四大组件) 构成的,包括 activities, fragments, services, content providers and broadcast receivers。
这些 app组件 中的大部分都是在 **应用清单(AndroidManifast.xml)**中声明的,Android操作系统使用这些组件来决定如何将应用程序集成到设备的用户体验中。虽然,如前所述,桌面应用程序通常上是以单个进程运行的,但是一个合理的Android应用需要更加灵活,因为用户可以通过不同的应用程序,在他们的设备上不断切换流程和任务。
例如,想象下在您最喜爱的社交网络应用中分享照片时会发生什么情况。这个应用程序触发了一个Camera(拍照或摄像)意图,由Android操作系统启动一个Camera应用来处理请求。此时,用户虽然离开了这个社交网络应用,但他们的体验是无缝的。相机应用程序又可能触发其他意图,例如启动文件选择器,该文件选择器可以启动另一个应用程序。最终用户回到社交网络应用并分享照片。此外,用户在这个过程的任何时候都可能被电话打断,并在打完电话后回来继续分享照片。
在Android中,这种应用程序跳转行为是很常见的,所以您的应用程序必须正确处理这些流程。请记住,移动设备是资源受限的,所以在任何时候,操作系统都可能需要杀死一些应用程序,以腾出空间给新的应用。
这一切的要点在于,您的 app组件 可以单独和无序地启动,并且可以在任何时候由用户或系统销毁。由于 app组件 是短暂的,并且它们的生命周期(创建和销毁时)不在您的控制之下,因此您不应该在app组件中存储任何 app数据或状态,并且 你的 app组件不应相互依赖。
通用架构原则
如果你不使用 app组件存储app数据和状态,那么应该如何构造应用程序呢?
你关注的最重要的事情是如何在你的应用中分离关注点。常见的错误是将所有的代码写入一个Activity或Fragment,任何不处理 UI 或 与操作系统交互的代码都不应该出现在这些类中,你应该尽可能保持 Activity或Fragment 精简,这样可以避免许多生命周期相关的问题。请记住,你不拥有这些类,它们只是建立操作系统和你的应用程序之间契约的胶水类。Android操作系统可能会随时根据用户交互或其他因素(如低内存)来销毁它们。最好尽可能地减少依赖他们,以提供可靠的用户体验。
第二个重要原则是 你应该从一个模型驱动你的UI,最好是一个持久化的模型。之所以说持久化是理想的模型,原因有两个:如果操作系统销毁你的应用程序以释放资源,那么你的用户就不会丢失数据,即使网络连接不稳定或连接不上,您的应用程序也会继续工作。模型是负责处理应用程序数据的组件。它们独立于应用程序的 Views 和 app组件,因此模型与这些 app组件的生命周期问题是相隔离的。保持简洁的UI代码,以及不受约束的应用程序逻辑,可以使app的管理更加容易,基于具有明确定义的管理数据责任的模型类的应用程序,会更加具有可测试性,并使您的应用程序状态保持前后一致。
推荐的App架构
在本节中,我们将演示如何通过使用用例来构造使用了 架构组件(Architecture Components) 的应用程序。
注意:不可能有一种对每个场景都是最好的编写应用程序的方法。也就是说,对于大多数用例来说,这个推荐的架构可能是一个好的起点。如果你已经有了编写Android应用的好方法,那就不要在更改了。
我们现在可以想象一下,假如我没正在搭建一个用来显示 用户概况的UI。该用户概况将使用 REST API从我们自己的服务器端获取。
搭建用户界面
这个UI 将由 UserProfileFragment.java 及 Fragment 相应的 user_profile_layout.xml 布局文件组成。
为了驱动用户界面,我们的数据模型需要保存两个数据元素。
-
用户ID:用户的标识符。最好使用 fragment 参数(setArguments方法) 将此信息传递到 fragment 中。如果Android系统销毁了你的进程,这些信息将被保留,便于应用在下次重新启动时可用。
-
用户对象:保存用户数据的 POJO(简单的Java对象)。
我们将创建一个基于ViewModel 的 UserProfileViewModel 类来保存这些信息。
一个 ViewModel 提供了一个特定 UI 组件中的数据,如一个 fragment 或 activity, 并且负责与数据处理业务的通信,例如调用其他app组件来加载数据或转发的用户信息的修改。ViewModel不知道View,并且不受配置更改的影响,例如由于屏幕旋转而重新创建 Activity。
现在我们有3个文件。
-
user_profile.xml:定义屏幕上的 UI。
-
UserProfileViewModel.java:为 UI 准备数据的类。
-
UserProfileFragment.java:显示 Vi