ViewModel优雅的弹加载窗和获取Context
Posted 滔lt
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ViewModel优雅的弹加载窗和获取Context相关的知识,希望对你有一定的参考价值。
前言
目前安卓开发一般都是用的mvvm模式,Jetpack的ViewModel是必不可少的一部分,而vm的生命周期要比Activity和Fragment长的,所以其一般不推荐其直接持有A或F,因为可能会造成内存泄漏的问题,但是不传入,Context的获取和显示网络加载弹窗又成了问题.
正文
首先解决显示网络加载弹窗的问题,其有两种方案:
1.使用MutableLiveData
首先我们在BaseViewModel中加入弹窗的MutableLiveData
val dialogShow = MutableLiveData(false)
然后我们可以在A或F的onCreate中获取vm的时候注册dialogShow的变化监听
val vm = ViewModelProvider(this).get(BaseViewModel::class.java)
vm.dialogShow.observe(this) { isShow ->
if (isShow) showWaitDialog() else dismissWaitDialog()
}
但是这样写太麻烦了,可以使用Kotlin的代理来简单实现,这样不仅声明的更方便,且自动注册了观察者
inline fun <reified VM : BaseViewModel> BaseActivity.baseViewModel() = lazy {
val vm = ViewModelProvider(this).get(VM::class.java)
vm.dialogShow.observe(this) { isShow ->
if (isShow) showWaitDialog() else dismissWaitDialog()
}
vm
}
//Activity中
val vm by baseViewModel<BaseViewModel>()
这样的优点很明显,vm完全不用持有A或F,但缺点是无法拿到A的Context
2.将BaseActivity或BaseFragment传入vm
就像androidViewModel一样,将A传入vm,但有的小伙伴可能会问了,那内存泄漏了怎么办?办法很简单,等下次重建回来的时候替换掉已经销毁的A即可,实现方式如下(示例为A,F也类似)
open class BaseViewModel(
var baseActivity: BaseActivity//内部用于弹窗等的引用
) : ViewModel(){
fun getContext() = baseActivity
fun showWaitDialog(s: String?) = baseActivity.showWaitDialog(s)
fun dismissWaitDialog() = baseActivity.dismissWaitDialog()
}
//快捷获取BaseViewModel
inline fun <reified VM : BaseViewModel> BaseActivity.baseViewModel(
factory: ViewModelProvider.Factory? = null
) = lazy {
val vm = ViewModelProvider(
this,
factory ?: BaseViewModelFactory(this@baseViewModel)
).get(VM::class.java)
vm.baseActivity = this
vm
}
class BaseViewModelFactory(private val baseActivity: BaseActivity) : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return modelClass.getConstructor(BaseActivity::class.java).newInstance(baseActivity)
}
}
//Activity中
val vm by baseViewModel<BaseViewModel>()
这样在A的每个对象中第一次使用vm的时候就会把baseActivity替换为自身,也就不存在内存泄漏的问题了
这样就可以愉快的在vm中使用网络加载弹窗和获取Context了
以上是关于ViewModel优雅的弹加载窗和获取Context的主要内容,如果未能解决你的问题,请参考以下文章