内容简介:Android Jetpack 是一套组件、工具和指导,可以帮助您快速构建出色的 Android 应用。每个 Jetpack 组件均可单独采用,并且它们依然可以流畅地协作。
Android Jetpack 是一套组件、 工具 和指导,可以帮助您快速构建出色的 Android 应用。
-
Google在17年的I/O大会上推出了架构组件(Architecture Component)工具集。
-
随后在18年I/O大会上发布了 Android Jetpack ,Jetpack 是Android开发组件工具集,旨在帮助我们轻松构建更稳定、更健壮、以及更可维护的应用程序。
每个 Jetpack 组件均可单独采用,并且它们依然可以流畅地协作。
Jetpack主要分为4个部分, 基础、架构、行为、界面 。从图中得知,Jetpack并不全是些新东西,只要是能够帮助开发者更好更方便地构建应用程序的组件,Google都将其归纳入了Jetpack,可以看出Google对jetpack很重视,对开发者很上心。
-
紧接着Google推出 AndroidX ,将许多Google认为是正确的方案和实践集中起来。
- AndroidX 是对support library的重大改进。
- AndroidX中的所有软件包名都以字符串androidx.开头,位于一致的命名空间中。
- 与support支持库不同,AndroidX软件包可单独维护和更新。
- 所有新的支持库开发都将在AndroidX库中进行。
官方推荐架构
使用此架构能带来什么好处?
-
UI和业务逻辑解耦。
-
有效避免生命周期组件内存泄漏。
- 提高模块可测试性。
- 提高应用稳定性,有效降低以下异常发生概率。
- Can not perform this action after onSaveInstanceState
- WindowManager$BadTokenException, is your activity running?
- OOM 、 NullPointerException
测试每个组件
-
界面和交互:使用 Android 界面插桩测试 。基于此架构只需mock 一个
ViewModel
即可完成界面测试。 -
ViewModel:使用 JUnit 测试 。只需mock一个类,即
Repository
。 -
Repository:使用 JUnit 测试 。只需mock两个类,XxxDao,XxxService;由于XxxDao,XxxService都是接口,还可以创建虚拟实现来完成复杂测试用例。
-
XxxDao:可以使用插桩测试来测试 DAO 类。这里注意对于每个测试,都请创建内存中数据库以确保测试没有任何副作用(例如更改磁盘上的数据库文件)。
-
XxxService:就Retrofit而言可以使用 MockWebServer 模拟本地服务器。
Lifecycle
Lifecycle是一个类,它包含组件(Activity或Fragment)生命周期状态的信息,并允许其他对象观察此状态。
跟踪组件生命周期
- Lifecycle内部使用两个主要枚举( Event 、 State )来跟踪其关联组件的生命周期状态。
- Event :对应Activity或Fragment组件的生命周期回调事件。
- State :表示被跟踪组件的当前状态,其中
STARTED
和RESUMED
为活跃状态,可接受到liveData的数据更新。
LifecycleOwner和LifecycleRegistry
- LifecycleOwner : 是一个单一的方法接口,表示该类具有生命周期。 support包从26.1.0版本开始,Fragment和Activity就默认实现了该接口。
- LifecycleRegistry : Lifecycle接口的实现类,协助组件处理生命周期,可处理多个观察者。如果你想自定义LifecyclerOwner请参考support包中Fragment和Activity实现。
ViewModel
ViewModel 是用来保存应用UI数据的类,它会在配置变更(Configuration Change)后继续存在。
生命周期
关于ViewModel的生命周期就一句话: 在Activity/Fragment等组件整个生命周期过程中,ViewModel的实例有且只有一个。
这样设计好处在哪呢?
- 可用ViewModel存储数据,它能安全度过手机旋转等配置变更场景。
- ViewModel能很好的实现多个Fragment之间的数据共享。
单一责任原则
上图为官方中文视频截图。
- Actvity或Fragment只显示UI和接收互动。
- 为避免ViewModel臃肿,可创建presenter处理UI数据。(比如从数据列表中获取某个item的属性)
- Repository 数据源操作入口。(便于单元测试)
- 配合其它架构组件使用。
最佳实践
- 如何时候都不要将Context传入ViewModel。
- 如果要在ViewModel中使用Application实例,请使用AndroidViewModel子类。
- ViewModel+LiveData+Databinding 可构建反应式UI。(请查看文末提供的参考资料)
-
ViewModel与onSaveInstanceState要配合使用。
ViewModel | onSaveInstanceState
—|—
能度过配置变更 | 能度过配置变更和进程关闭
存储大量数据 | 存储少量数据
| 可序列化
ViewModel和onSaveInstanceState是相辅相成的,当进程被关闭时,ViewModel会被销毁,而onSaveInstanceState不会受影响。所以用onSaveInstanceState存储少量关键数据(如xxxId),并在该场景恢复后用来加载页面数据。
ViewModel和View之间通信
- UserProfileActivity引用UserViewModel,可观察其提供的UserLiveData、StatusLiveData、PageStateLiveData数据源变更来刷新UI。
- 响应用户事件,比如更新用户信息。Activity将更新事件传递给ViewModel,ViewModel有将其委托给Presenter处理,Presenter处理过程及结果通过LiveData与Activity交互。
- 注意Activity和ViewModel之间是单向引用。 为避免内存泄漏,ViewModel不能持有任何Context引用。
LiveData
LiveData是一个具有生命周期感知特性的可观察的数据保持类。
- LiveData只通知活跃状态(
STARTED
orRESUMED
)的Observer更新,并在DESTROYED
状态时自动移除Observer,避免内存泄漏。 - 始终保持最新数据。举例:1.退后台的Activity在返回前台后会立即收到最新数据。2. 配置变更导致Activity重建后也会立即收到最新数据。
- 共享资源。单利模式共享同一个LiveData。
LiveData、MutableLiveData、MediatorLiveData区别?
- 继承关系:MediatorLiveData -> MutableLiveData -> LiveData。 所以MediatorLiveData功能最强大。
- LiveData 是一个具有生命周期感知的可观察的数据保持类。
- MutableLiveData 在LiveData基础上打开了修改Value的方法权限。
- MediatorLiveData 可管理多个LiveData。
Transformations
-
map: 将一种数据类型的
// 观察将被转换LiveData,待其数据源变更后转换为LiveData 并通知订阅者。
// 内部使用的MediatorLiveData实现。
LiveData
userLiveData = …; LiveData<String> userName = Transformations.map(userLiveData, user -> { user.name + " " + user.lastName
});
- **switchMap** : 和map类似。差别在于triggerLiveData变更后,会触发和等待另外一个LiveData获取数据。
// 实例代码:将addressInputLiveData转换为postalCodeLiveData.
class MyViewModel extends ViewModel {
private final PostalCodeRepository repository;
private final MutableLiveDataaddressInput = new MutableLiveData();
public final LiveData
postalCode = Transformations.switchMap(addressInput, (address) -> { return repository.getPostCode(address); }); public MyViewModel(PostalCodeRepository repository) { this.repository = repository }
// addressInputLiveData变更时触发repository.getPostCode,
// 待其回去成功后,再将数据设置给postalCodeLiveData。
private void setInput(String address) { addressInput.setValue(address); }
}
```
几个问题
LifecycleOwner组件是如何与liveData通信的?
- SupportActivity 通过添加一个空的ReportFragment来处理生命周期状态变更回调;Fragment则在自身生命周期函数中处理。
- LifecycleOwner组件,通过LifecycleRegistry类中handleLifecycleEvent -> dispatchEvent方法与liveData通信,从而是liveData具有自动感知组件生命周期的能力。
- 组件销毁时,LifecycleRegistry会通知liveData移除observer。
ViewModel如何做到一直在内存中,直到Activity销毁或Fragment被移除时才被清除的?
1.x.x版本实现
- Activity或Fragment会添加一个空的HolderFragment,而ViewModelStore实例被HolderFragment持有,所以就保证了整个生命周期中ViewModelStore实例始终唯一,也就保证了其缓存的ViewModel实例会一直存在直到组件销毁(在onDestroy中会调用ViewModelStore.clear()方法清除其缓存的ViewModel实例)。
- 由于这个HolderFragment设置了setRetainInstance(true), 这样在Activity重建时它不会执行onDestroy回调,这就是它能度过配置变更的原因 。
以上所述就是小编给大家介绍的《Android Jetpack 架构组件最佳实践》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- MVVM 架构解析及 Jetpack 架构组件的使用
- MVVM 架构解析及 Jetpack 架构组件的使用
- 微服务架构————基本组件
- 组件化架构漫谈
- Rabbitmq基础组件架构设计
- Android组件化入门:一步步搭建组件化架构
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
构建高可用Linux服务器(第3版)
余洪春 / 机械工业出版社 / 2014-10 / 79.00元
《构建高可用Linux服务器(第3版)》是Linux运维领域公认的经典畅销书,是国内51CTO、IT168等知名网站和多位资深运维专家共同推荐的运维工程师必备的工具书! “酒哥”在Linux运维领域潜心实践近10年,一直在运维一线,技术和思维都紧跟时代的发展,非常清楚运维工程师们需要什么,应该学习什么。本书不仅是他近10年工作经验的结晶,同时也是他的数万名读者和数十万粉丝共同需求和集体智慧的......一起来看看 《构建高可用Linux服务器(第3版)》 这本书的介绍吧!