10-JetPack项目实战-实现App共享ViewModel
前提
看懂本文的前提是,了解ViewModel源码,Activity是如何存储ViewModel保证数据稳定性的。
本文使用Kotlin编写。
简介
在App开发过程中,会遇到需要全局共享的数据,例如:用户登录信息。
在使用MVVM框架时,ViewModel+DataBinding+LiveData来实现界面和ViewModel双向绑定的时候。使用ViewModel来存储数据,当ViewModel中的LiveData数据发生改变时,能同时更新界面的数据。
此时就会需要一个全局共享的ViewModel。当用户信息改变的时候,需要通知所有与用户相关的界面。(正在展示的和未展示的)
思路
如何实现一个全局共享的ViewModel呢?
在Applicaiton中直接创建和实例化一个全局共享ViewModel可以,Activity/Fragment中使用Applicaiton来获取ViewModel当然可以。
此文提供一种更好的方式,让共享ViewModel同普通ViewModel一样使用。
模拟普通ViewModel的创建过程,在Applicaiton中创建一个唯一的ViewModelStore来存储共享ViewModel,来保证共享VIewModel的唯一性。
在BaseActivity/BaseFragment中声明并通过Applicaiton获取共享ViewModel,让所有实现了BaseActivity/BaseFragment的Activity/Fragment都拥有一个共享ViewModel变量。
实现
全局App类,提供唯一ViewModelStore,ViewModelStore用于存储共享ViewModel,保证共享ViewModel的唯一性。
要点:
- App要实现ViewModelStoreOwner接口。
- ViewModelStore的实例化要保证唯一(在onCreate中实例化)。
- 创建ViewModelProvider时要注意传入的ViewModelStoreOwner对象,要是App类对象,才能保证获取到的是App类中实例化的ViewModelStore对象。
- ViewModelStoreOwner接口的函数getViewModelStore()的返回对象要是App类中的ViewModelStore对象。
import android.app.Activity
import android.app.Application
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelStore
import androidx.lifecycle.ViewModelStoreOwner
class App :Application(),ViewModelStoreOwner{
//ViewModelStore单例,在整个系统中只有一个对象
private var mAppViewModelStore:ViewModelStore? = null
private var mFactory:ViewModelProvider.Factory? = null
override fun onCreate() {
super.onCreate()
//ViewModelStor初始化
mAppViewModelStore = ViewModelStore()
}
fun getAppViewModelProvider(activity: Activity):ViewModelProvider{
/**
* 创建ViewModelProvider对象
* 第一个参数是ViewModelStoreOwner类型,用于使用getViewModelStore()获取ViewModelStore,此处需要使用的是
* 在App类中声明的mAppViewModelStore变量,为了获取到该变量,让App类实现ViewModelStoreOwner接口以及其getViewModelStore()方法。
*
* 第二个参数是ViewModelProvider.Factory类型,使用getAppFactory()方法返回一个AndroidViewModelFactory对象。
* AndroidViewModelFactory对象传入的Activity,让共享ViewModel能获取到Activity对象,可以进行页面跳转。
*/
return ViewModelProvider(activity.applicationContext as App,getAppFactory(activity)!!)
}
private fun getAppFactory(activity: Activity):ViewModelProvider.Factory?{
val applicaiton = checkApplication(activity)
if(mFactory == null) {
//注意此处创建AndroidViewModelFactory,传入的是Activity,而不是App
return ViewModelProvider.AndroidViewModelFactory.getInstance(applicaiton)
}
return mFactory
}
// 监测下 Activity是否为null
private fun checkApplication(activity: Activity): Application {
return activity.application
?: throw IllegalStateException(
"Your activity/fragment is not yet attached to "
+ "Application. You can't request ViewModel before onCreate call."
)
}
//注意要返回mAppViewModelStore,才能保证ViewModelStore的唯一性
override val viewModelStore: ViewModelStore
get() = mAppViewModelStore!!
}
共享ViewModel类
import androidx.lifecycle.ViewModel
/**
* SharedViewModel的职责是用于 页面通信的
* 共享数据,解决一致性问题
*/
class SharedViewModel : ViewModel() {
}
基类BaseActivity的实现。
import android.graphics.Color
import android.os.Bundle
import android.os.PersistableBundle
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModelProvider
import com.learn.common.bridge.App
import com.xiangxue.architecture.bridge.callback.SharedViewModel
import com.xiangxue.architecture.utils.BarUtils
open class BaseActivity:AppCompatActivity() {
//声明共享ViewModel对象
private lateinit var sharedViewModel:SharedViewModel
override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {
super.onCreate(savedInstanceState, persistentState)
//实例化共享ViewModel对象
sharedViewModel = getAppViewModelProvider().get(SharedViewModel::class.java)
}
//确保ViewModelProvider是单例
private fun getAppViewModelProvider():ViewModelProvider{
return (applicationContext as App).getAppViewModelProvider(this)
}
}
原文地址:https://blog.csdn.net/li1500742101/article/details/142640760
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!