本文主要内容:
- 作用介绍
- 核心类介绍
- 基本使用
- 源码分析
– 横竖屏切换恢复
– 后台销毁恢复
ViewModel的主要工作:
本身主要是一个数据维护工具
将数据维护的工作从Activity
上剥离,提供一个储存数据环境,自身机制可以解决开发中,数据受Activity
生命周期影响产生数据丢失的问题 (主要为横竖屏切换以及在后台被销毁)。
通常结合LiveData
使用。
作为一个纯数据维护工具,可以加入到MVP
架构中负责数据保存。
而官方推选作为AAC
架构MVVM
中的VM
层。
ViewModel的主要类:
-
ViewModel (下称VM)
:
数据储存类,架构的核心类。
使用时,直接继承该类,根据需求选择重写onCleared()
方法。
如需在Activity
被系统销毁后依然保存数据,定义一个参数为(SavedStateHandle)
的构造方法,并将数据保存SavedStateHandle
中。
实际上通过SavedInstanceState
存取 -
AndroidViewModel
:
VM
子类,维护了Application
的引用,由架构中的SavedStateViewModelFactory
创建时传入。
同样,需要接收SavedStateHandle
时,需要定义参数为(Application, SavedStateHandle)
的构造方法。 -
ViewModelStore
:
用于保存VM
,内部维护了一个用于储存VM
的HashMap
。
一般情况下,直接使用本类创建实例。 -
ViewModelStoreOwner
:
接口,实现该接口的类,表示自身能够向外提供VM
。
androidx 的AppCompatActivity
/Fragment
实现了该接口。 -
ViewModelProvider
:
VM
的提供者,获取VM
的基本入口。
实际依赖ViewModelStore
存取VM
,Factory
生成/恢复VM
。 -
Factory
:
接口,实现该接口的类主要用于创建VM
实例。
不建议直接实现该接口,除非你清楚框架内容和自己的需求。
一般情况下,如果无需SavedStateHandle
机制,可以使用AndroidViewModelFactory
。
否则应该使用或继承SavedStateViewModelFactory
。
ViewModel的基本使用:
- 一般使用:
// VM
class ViewModelA : ViewModel()
// AVM
class ViewModelB(app: Application) : AndroidViewModel(app)
// Activity/Fragment .onCreate中
override fun onCreate() {
...
val provider = ViewModelProvider(this)
val vmA = provider.get(ViewModelA::class.java)
val vmB = provider.get(ViewModelB::class.java)
...
}
- 接受 SavedStateHandle
// VM
class ViewModelC(
val handle: SavedStateHandle
) : ViewModel()
// AVM
class ViewModelD(
app: Application,
val handle: SavedStateHandle
) : AndroidViewModel(app)
- 跨 Fragment 共享数据
Fragment中直接以Activity作为ViewModel的Key
...
val provider = ViewModelProvider(requireActivity())
val vmA = provider.get(ViewModelA::class.java)
- 通过 Application 创建全局共享的 VM
class App : Application(), ViewModelStoreOwner {
private lateinit var mAppViewModelStore: ViewModelStore
private lateinit var mFactory: ViewModelProvider.Factory
override fun onCreate() {
super.onCreate()
mAppViewModelStore = ViewModelStore()
mFactory = ViewModelProvider
.AndroidViewModelFactory
.getInstance(this)
}
override fun getViewModelStore(): ViewModelStore {
return mAppViewModelStore
}
private fun getAppFactory(): ViewModelProvider.Factory {
return mFactory
}
fun getAppViewModelProvider(activity: Activity): ViewModelProvider {
val app = checkApplication(activity) as App
return ViewModelProvider(app, app.getAppFactory())
}
fun getAppViewModelProvider(fragment: Fragment): ViewModelProvider {
return getAppViewModelProvider(fragment.requireActivity())
}
private fun checkApplication(activity: Activity): Application {
return activity.application
?: throw IllegalStateException(
"Your activity is not yet attached to the Application instance." +
"You can't request ViewModel before onCreate call.")
}
}
ViewModel的关键源码分析:
以下源码分析将会去除非相关代码以简化
- ViewModelProvider 实现相关:
前面提到,ViewModelProvider
的工作完全依赖传入的ViewModelStore
和Factory
,可以直接从构造方法得知:
ViewModelProvider.java
----------------------
private final Factory mFactory;
private final ViewModelStore mViewModelStore;
public ViewModelProvider(ViewModelStoreOwner owner) {
this(owner.getViewModelStore(),
owner instanceof HasDefaultViewModelProviderFactory
? ((HasDefaultViewModelProviderFactory) owner)
.getDefaultViewModelProviderFactory()
: NewInstanceFactory.getInstance());
}
public ViewModelProvider(ViewModelStoreOwner owner, Factory factory) {
this(owner.getViewModelStore(), factory);
}
public ViewModelProvider(ViewModelStore store, Factory factory) {
mFactory = factory;
mViewModelStore = store;
}
// 简单的反射创建实例的工厂
public static class NewInstanceFactory implements Factory {
public <T extends ViewModel> T create(Class<T> modelClass) {
return modelClass.newInstance()
}
}
而androidx.activity.ComponentActivity
,androidx.fragment.app.Fragment
都实现了ViewModelStoreOwner
,HasDefaultViewModelProviderFactory
接口。
public class AppCompatActivity extends FragmentActivity...{}
public class FragmentActivity extends ComponentActivity...{}
public class ComponentActivity extends ... implements
ViewModelStoreOwner,
HasDefaultViewModelProviderFactory,
SavedStateRegistryOwner ... {}
public class Fragment implements
ViewModelStoreOwner,
HasDefaultViewModelProviderFactory,
SavedStateRegistryOwner ... {}
ViewModelProvider
的get()
方法中返回<