目录
1. 官网对于Lifecycle的介绍
2. 却把清梅嗅的系列博客介绍
3. Chaos Leong的深度介绍Lifecycle原理的文章
4. 关于LiveData的使用
5. 官网关于Transform LiveData的介绍
1. Transformations.map()
2. Transformations.switchMap()
6. MediatorLiveData的使用
7. Learn how to use LiveData
8. 关于LiveDataReactiveStreams的使用
9. 更多详细内容介绍,请访问以下文档链接
Handling Lifecycles with Lifecycle-Aware Components
这里Core Topics里有个Architecture Components 专题,包含里其他的LiveData和ViewModel的介绍。
如果英语不好的,可以看翻译版:
[译] Architecture Components 之 Handling Lifecycles
这也是一系列翻译文章,包含了LiveData和ViewModel的翻译介绍。
Android官方架构组件:Lifecycle详解&原理分析
ShymanZhu的Android 架构组件(一)——Lifecycle
Lifecycle-aware Components 源码分析
该博主的其他一些博客也极有学习价值,比如:LiveData 源码分析
Architecture Components 之 LiveData
除了可以在一个Activity或者Fragment里之外,由于LiveData是生命周期感知的,所以可以在多个Activity和Fragment之间公用,一个简单的例子就是实现LiveDate,将实现类写成单例模式。如官网描述:
The fact that LiveData
objects are lifecycle-aware means that you can share them between multiple activities, fragments, and services. To keep the example simple, you can implement the LiveData
class as a singleton as follows:
class StockLiveData(symbol: String) : LiveData() {
private val mStockManager: StockManager = StockManager(symbol)
private val mListener = { price: BigDecimal ->
value = price
}
override fun onActive() {
mStockManager.requestPriceUpdates(mListener)
}
override fun onInactive() {
mStockManager.removeUpdates(mListener)
}
companion object {
private lateinit var sInstance: StockLiveData
@MainThread
fun get(symbol: String): StockLiveData {
sInstance = if (::sInstance.isInitialized) sInstance else StockLiveData(symbol)
return sInstance
}
}
}
然后可以这样在Fragment中使用:
class MyFragment : Fragment() {
override fun onActivityCreated(savedInstanceState: Bundle?) {
StockLiveData.get(symbol).observe(this, Observer { price: BigDecimal? ->
// Update the UI.
})
}
Multiple fragments and activities can observe the MyPriceListener
instance. LiveData only connects to the system service if one or more of them is visible and active.
https://developer.android.com/topic/libraries/architecture/livedata
有时候,为了在将LiveData的数据传递到观察者之前,想做一些数据变换,或者基于当前的LiveData,返回另外一个LiveData实例,Transformations
类提供了两个函数:
Transformations.map()
Applies a function on the value stored in the LiveData
object, and propagates the result downstream.
对存储在LiveData对象中的值应用函数,并将结果传播到下游
val userLiveData: LiveData = UserLiveData()
val userName: LiveData = Transformations.map(userLiveData) {
user -> "${user.name} ${user.lastName}"
}
2.
Transformations.switchMap()
Similar to map()
, applies a function to the value stored in the LiveData
object and unwraps and dispatches the result downstream. The function passed to switchMap()
must return a LiveData
object, as illustrated by the following example:
与map()类似,将函数应用于存储在LiveData对象中的值,并将结果解包并调度到下游。 传递给switchMap()的函数必须返回一个LiveData对象,如以下示例所示:
private fun getUser(id: String): LiveData {
...
}
val userId: LiveData = ...
val user = Transformations.switchMap(userId) { id -> getUser(id) }
使用这些转换允许在整个调用链中携带观察者的 Lifecycle 信息,以便只有在观察者观察到 LiveData 的返回时才运算这些转换。转换的这种惰性运算性质允许隐式的传递生命周期相关行为,而不必添加显式的调用或依赖。
每当你认为在 ViewModel 中需要一个 Lifecycle 类时,转换可能是解决方案。
⚠️注意:For example, assume that you have a UI component that accepts an address and returns the postal code for that address. You can implement the naive ViewModel
for this component as illustrated by the following sample code:
这时候不要像下面代码这样处理:
class MyViewModel(private val repository: PostalCodeRepository) : ViewModel() {
private fun getPostalCode(address: String): LiveData {
// DON'T DO THIS
return repository.getPostCode(address)
}
}
The UI component then needs to unregister from the previous LiveData
object and register to the new instance each time it calls getPostalCode()
. In addition, if the UI component is recreated, it triggers another call to therepository.getPostCode()
method instead of using the previous call’s result.
Instead, you can implement the postal code lookup as a transformation of the address input, as shown in the following example:
class MyViewModel(private val repository: PostalCodeRepository) : ViewModel() {
private val addressInput = MutableLiveData()
private val postalCode: LiveData =
Transformations.switchMap(addressInput) { address -> repository.getPostCode(address) }
private fun setInput(address: String) {
addressInput.value = address
}
}
MediatorLiveData的使用
Merge multiple LiveData sources
MediatorLiveData
is a subclass of LiveData
that allows you to merge multiple LiveData sources. Observers of MediatorLiveData
objects are then triggered whenever any of the original LiveData source objects change.
For example, if you have a LiveData
object in your UI that can be updated from a local database or a network, then you can add the following sources to the MediatorLiveData
object:
LiveData
object associated with the data stored in the database.LiveData
object associated with the data accessed from the network.Your activity only needs to observe the MediatorLiveData
object to receive updates from both sources. For a detailed example, see the Addendum: exposing network status section of the Guide to App Architecture.
这里单独把jensklin的关于如何使用LiveData的系列博客列出来,jensklin录制了很多关于LiveData的视频,在该篇博客中也可以看到,值得学习,博客里也包含了LiveDataReactiveStreams的使用
Contents [hide]
对于LiveDataReactiveStreams,可能大家还比较陌生,这里找了一些使用例子。以后希望自己也能多写一些,来做补充。
1. Java Code Examples for LiveDataReactiveStreams
2. 一个LiveDataReactiveStreamsActivity.kt
> 架构组件的官方开发者文档:
https://developer.android.google.cn/arch
> ViewModel 的文档:
https://developer.android.google.cn/topic/libraries/architecture/viewmodel.html
> 应用程序架构指南:
https://developer.android.google.cn/topic/libraries/architecture/guide.html
> 使用生命周期管理库的架构组件实例
- Java:
https://github.com/googlesamples/android-architecture/tree/dev-todo-mvvm-live/
- Kotlin:
https://github.com/googlesamples/android-architecture/tree/dev-todo-mvvm-live-kotlin/
架构组件实例:
> https://github.com/googlesamples/android-architecture-components
ViewModelFactory 实例:
> https://github.com/googlesamples/android-architecture/blob/dev-todo-mvvm-live/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/ViewModelFactory.java
Android 生命周期备忘录:
> https://juejin.im/post/5a77c9aef265da4e6f17bd51