Jetpack系列(三) — LiveData,2021最新阿里Android面经
作者:互联网
LiveData 基本使用
简单使用
- 创建
LiveData
对象,LiveData
是一种可用于任何数据的封装容器,存放在ViewModel
当中
class HomeViewModel : ViewModel() {
private var tapCount = 0
private var _taps = MutableLiveData("$tapCount taps")
val taps: LiveData
get() = _taps
fun updateTaps() {
tapCount++
_taps.postValue("$tapCount taps")
}
}
- 观察
LiveData
对象
// HomeFragment.kt
private val viewModel: HomeViewModel by viewModels()
// 观察Observer
viewModel.taps.observe(viewLifecycleOwner, ::tapsUpdate)
private fun tapsUpdate(s: String?) {
binding.tvCount.text = s ?: “”
}
- 更新
LiveData
对象
MutableLiveData
类将公开setValue(T)
和postValue(T)
方法,
// 触发
binding.btnAdd.setOnClickListener {
viewModel.updateTaps()
}
复制代码
扩展LiveData
- 继承
LiveData
,自定义LiveData
实现扩展功能,重写onActive()
和onInactive()
方法
-
当
LiveData
对象具有活跃观察者时,会调用onActive()
方法 -
当
LiveData
对象没有任何活跃观察者时,会调用onInactive()
-
setValue(T)
方法将更新LiveData
实例的值,并将更改告知活跃观察者。
// 官方代码
class StockLiveData(symbol: String) : LiveData() {
private val stockManager: StockManager = StockManager(symbol)
private val listener = { price: BigDecimal ->
value = price
}
override fun onActive() {
stockManager.requestPriceUpdates(listener)
}
override fun onInactive() {
stockManager.removeUpdates(listener)
}
companion object {
private lateinit var sInstance: StockLive
《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享
Data
@MainThread
fun get(symbol: String): StockLiveData {
sInstance = if (::sInstance.isInitialized) sInstance else StockLiveData(symbol)
return sInstance
}
}
}
- 观察
StockLiveData
StockLiveData.get(symbol).observe(viewLifecycleOwner, Observer { price: BigDecimal? ->
// Update the UI.
})
转换LiveData
Lifecycle
软件包会提供Transformations
类,可以根据另一个实例的值返回不同的LiveData
实例,在将 LiveData 对象分派给观察者之前对存储在其中的值进行更改
map()
用于将实际包含数据的LiveData
和仅用于观察数据的LiveData
进行转换
//User.kt
data class User(var firstName: String, var lastName: String, var age: Int)
//HomeViewModel.kt
class HomeViewModel : ViewModel() {
private val _userLiveData = MutableLiveData()
val userName: LiveData = Transformations.map(_userLiveData) { user ->
“${user.firstName} ${user.lastName}”
}
fun updateTaps() {
_userLiveData.postValue(User(“aa”, “bb”, 12))
}
}
switchMap()
对存储在LiveData
对象中的值应用函数
//HomeViewModel.kt
class HomeViewModel : ViewModel() {
private val _userIdLiveData = MutableLiveData()
val user: LiveData = Transformations.switchMap(_userIdLiveData) { userId ->
Repository.getUser(userId)
}
fun updateTaps() {
_userIdLiveData.postValue(“cc”)
}
}
// 测试
object Repository {
fun getUser(userId: String): LiveData {
val liveData = MutableLiveData()
liveData.value = User(userId, userId, 0)
return liveData
}
}
合并多个 LiveData 源
MediatorLiveData
允许合并多个 LiveData 源,适用于一个观察者,多个被观察者
//HomeViewModel.kt
class HomeViewModel : ViewModel() {
private val _user1 = MutableLiveData()
private val _user2 = MutableLiveData()
var mediatorLiveData: MediatorLiveData = MediatorLiveData()
init {
mediatorLiveData.addSource(_user1) {
mediatorLiveData.value = it
}
mediatorLiveData.addSource(_user2) {
mediatorLiveData.value = it
}
}
fun updateTaps() {
_user1.postValue(User(“ll”, “nn”, 12))
_user2.postValue(User(“xx”, “bb”, 12))
}
}
// HomeFragment.kt
…
private fun subscribeUI() {
observe(viewModel.mediatorLiveData, ::mediatorLiveDataUpdate)
}
private fun mediatorLiveDataUpdate(user: User?) {
Log.e("==========","$user")
}
相关知识点
知识点一:
postValue
和setValue
setValue
需要运行在主线程,postValue
不用
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
@MainThread
protected void setValue(T value) {
assertMainThread(“setValue”);
mVersion++;
mData = value;
dispatchingValue(null);
}
如果想进阶学习jetpack又缺少学习资料,而我正好薅到这本阿里十年技术专家联合打造“最新”《Jetpack架构组件入门到精通》和《Jetpack强化实战手册》,是你学习Jetpack的葵花宝典。
点击此处蓝字免费获取
1.创建项目
2.沉浸式的布局
3.富文本
4.属性动画
二、Navigation实践之实现APP主框架以及Navigation的相关介绍
标签:val,Jetpack,面经,HomeViewModel,private,postValue,LiveData,fun 来源: https://blog.csdn.net/m0_65512512/article/details/122219498