Android 面试总结 - LiveData

LiveData 是什么?

LiveData 是 JetPack 的一部分。

LiveData 是一种可观察的数据存储器类。与常规的可观察类不同,LiveData 具有生命周期感知能力,意指它遵循其他应用组件(如 Activity、Fragment 或 Service)的生命周期。这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者。

如果观察者(由 Observer 类表示)的生命周期处于 STARTED状态,则 LiveData 会认为该观察者处于活跃状态。LiveData 只会将更新通知给活跃的观察者。为观察 LiveData 对象而注册的非活跃观察者不会收到更改通知。

您可以注册与实现 LifecycleOwner接口的对象配对的观察者。有了这种关系,当相应的 Lifecycle对象的状态变为 DESTROYED时,便可移除此观察者。这对于 Activity 和 Fragment 特别有用,因为它们可以放心地观察 LiveData对象,而不必担心泄露(当 Activity 和 Fragment 的生命周期被销毁时,系统会立即退订它们)。

摘自官方文档:LiveData 概览
LiveData 相关问题是面试高频题,因为他具有生命周期感知能力,支持黏性事件,采用了观察者模式,某种程度上也可以用作事件总线。
根据官方文档我们知道它的主要作用:数据持有存储器类、可观察类、具有生命周期感知能力。

问题来了:

  1. LiveData 怎么感知生命周期感知?需要取消注册吗?
  2. setValue 和 postValue 有什么区别
  3. 设置相同的值,订阅的观察者们会收到同样的值吗
  4. 粘性事件原理,怎么防止数据倒灌
  5. observeForever怎么用

基本使用

MainRepository

class MainRepository {
    suspend fun getNameList(): List<String> {
        // 获取数据切到工作线程,模拟网络请求过程
        return withContext(Dispatchers.IO) {
            listOf("张三", "李四")
        }
    }
}

MainViewModel

class MainViewModel: ViewModel() {
    private val nameList = MutableLiveData<List<String>>()
    val nameListResult: LiveData<List<String>> = nameList
    private val mainRepository = MainRepository()

    fun getNames() {
        // 使用协程模拟请求过程
        viewModelScope.launch {
            nameList.value = mainRepository.getNameList()
        }
    }
}

MainActivity

class MainActivity : AppCompatActivity() {
    // 创建 ViewModel 方式 1
    // 通过 kotlin 委托特性创建 ViewModel
    // 需添加依赖 implementation 'androidx.activity:activity-ktx:1.2.3'
    // viewModels() 内部也是通过 创建 ViewModel 方式 2 来创建的 ViewModel
    private val mainViewModel: MainViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate  (savedInstanceState)
        setContentView(R.layout.activity_main)
        // 创建 ViewModel 方式 2
        val mainViewModel = ViewModelProvider(this).get(MainViewModel::class.java)
        // 通过 LiveData.observe 订阅观察者
        mainViewModel.nameListResult.observe(this, {
            Log.i("MainActivity", "mainViewModel: nameListResult: $it")
        })
        mainViewModel.getNames()
    }
}

打开app -> 正常看到日志

18:03:02.575 : mainViewModel: nameListResult: [张三, 李四]

源码解析

LiveData 通过 observe 方法来订阅观察者,以此为查看源码的入口:

方法注释包含的知识很多,请认真阅读注释 (百度翻译过来的)。

private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =
        new SafeIterableMap<>();
/**
 * 1、在给定 owner 的生命周期内,将给定的观察者添加到观察者列表中。
 * 2、事件在主线程上调度。
 * 3、如果LiveData已经有数据集,它将被交付给观察者。
 * <p>
 * 4、仅当所有者处于{@link Lifecycle.State#STARTED}或{@link Lifecycle.State#RESUME}状态
 *(活动)时,观察者才会接收事件。
 * <p>
 * 5、如果所有者移动到{@link Lifecycle.State#DETROYED}状态,观察者将自动被删除。
 * <p>
 * 6、当数据在{@code owner}未激活时发生更改时,它将不会收到任何更新。
 * 7、如果它再次激活,它将自动接收最后可用的数据。
 * <p>
 * 8、只要给定的LifecycleOwner未被销毁,LiveData就会保留对观察者和所有者的强引用。
 * 9、销毁后,LiveData将删除对所有者的引用。
 * <p>
 * 10、如果给定的所有者已经处于{@link Lifecycle.State#DESTROYED}状态,LiveData将忽略该调用。
 * <p>
 * 11、如果给定的所有者、观察者元组已经在列表中,则忽略该调用。
 * 12、如果观察者已经列表中,LiveData将抛出@link IllegalArgumentException}。
 *
 * @param owner    控制观察者的生命周期所有者
 * @param observer 将接收事件的观察者
 */
@MainThread
publi
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值