今天是2022年9月16日 星期五
座位朝向:面向西方写程序,BUG 最少。
今日宜饮:水,果味汽水
女神亲近指数:2.4
ViewModel以绑定生命周期的方式存储和管理界面相关数据,当设备发生屏幕旋转等配置更改后继续保留页面数据。
在ViewModel之前,通常的做法是使用activity的onSaveInastanceState()方法从onCreate()中恢复保存的数据,但是这个方法只适合可以序列化和反序列化的少量数据,并不适合数据较大的数据。 ViewModel除了能够存储和管理界面相关数据外,还能通过对Activity的生命周期监听,在系统销毁后主动释放资源,避免发生内存泄漏。
class MainViewModel:ViewModel() {
val mainLiveData = MutableLiveData()
}
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val viewModel = ViewModelProvider(this, ViewModelProvider.NewInstanceFactory()).
get(MainViewModel::class.java)
viewModel.mainLiveData.observe(this){
}
}
通过定义一个MainViewModel类继承自ViewModel抽象类,然后再Activity中初始化MainViewModel。
如果需要在ManViewModel中使用context,MainViewModel需要继承AndroidViewModel。
class MainViewModel(application: Application):AndroidViewModel(application) {
val mainLiveData = MutableLiveData()
}
val viewModel = ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory(application)).get(MainViewModel::class.java)
viewModel.mainLiveData.observe(this){
}
ViewModel为什么能够临时保存界面数据状态?因为ViewModel的作用域包括了整个Activity的生命周期,随着Activity被销毁而清空。
通常该系统首次调用 Activity 对象的 onCreate() 方法是初始化 ViewModel。系统可能会在 activity 的整个生命周期内多次调用 onCreate(),如在旋转设备屏幕时。ViewModel 存在的时间范围是从首次请求 ViewModel 直到 activity 完成并销毁。
首先从Activity的父类ComponentActivity开始,实现了ViewModelStoreOwner接口,
public class ComponentActivity extends androidx.core.app.ComponentActivity implements
ContextAware,
LifecycleOwner,
ViewModelStoreOwner,
}
public interface ViewModelStoreOwner {
/**
* Returns owned {@link ViewModelStore}
*
* @return a {@code ViewModelStore}
*/
@NonNull
ViewModelStore getViewModelStore();
}
public class ViewModelStore {
private final HashMap mMap = new HashMap<>();
final void put(String key, ViewModel viewModel) {
ViewModel oldViewModel = mMap.put(key, viewModel);
if (oldViewModel != null) {
oldViewModel.onCleared();
}
}
final ViewModel get(String key) {
return mMap.get(key);
}
Set keys() {
return new HashSet<>(mMap.keySet());
}
/**
* Clears internal storage and notifies ViewModels that they are no longer used.
*/
public final void clear() {
for (ViewModel vm : mMap.values()) {
vm.clear();
}
mMap.clear();
}
}
由于ComponentActivity实现了ViewModelStoreOwner接口,在ComponentActivity中调用getViewModelStore可以获取ViewModel的存储类ViewModelStore,ViewModelStore中使用HashMap存储ViewModel,如果存储的ViewModel的key值相同,则删除oldViewModel旧的ViewModel,替换成最新的ViewModel。
我们来看一下ComponentActivity中是如果保存使用ViewModelStore。
ComponentActivity的构造函数
public ComponentActivity() {
Lifecycle lifecycle = getLifecycle();
......................
.........................
//使用lifecycle对activity生命周期进行监听
getLifecycle().addObserver(new LifecycleEventObserver() {
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
//如果生命周期为onDestory
if (event == Lifecycle.Event.ON_DESTROY) {
// 清除context
mContextAwareHelper.clearAvailableContext();
//如果应用配置没有发生改变
if (!isChangingConfigurations()) {
//清除ViewModelStore中HashMap存储的ViewModel
getViewModelStore().clear();
}
}
}
});
getLifecycle().addObserver(new LifecycleEventObserver() {
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
//初始化ViewModelStore
ensureViewModelStore();
getLifecycle().removeObserver(this);
}
});
当ComponentActivity退出销毁时,会调用getViewModelStore().clear(),清除ViewModelStore中HashMap存储的ViewModel,释放资源。我们接着看数据是如何保存的?
void ensureViewModelStore() {
//如果存储类为null
if (mViewModelStore == null) {
NonConfigurationInstances nc =
(NonConfigurationInstances) getLastNonConfigurationInstance();
if (nc != null) {
// 从 NonConfigurationInstances 恢复 ViewModelStore
mViewModelStore = nc.viewModelStore;
}
if (mViewModelStore == null) {
mViewModelStore = new ViewModelStore();
}
}
}
static final class NonConfigurationInstances {
Object custom;
ViewModelStore viewModelStore;
}
NonConfigurationInstances是一个静态类,它有两个成员变量Object 和ViewModelStore ;如果ViewModelstore如果不存在,则将NonConfigurationInstances的成员变量保存的ViewModelstore赋值给ViewModelStore 。我们接着看一下getLastNonConfigurationInstance。
//获取上一次保存的数据
@Nullable
public Object getLastNonConfigurationInstance() {
return mLastNonConfigurationInstances != null
? mLastNonConfigurationInstances.activity : null;
}
mLastNonConfigurationInstances 是上一次保存的数据实例,当Activity被创建的时候,调用attach方法,mLastNonConfigurationInstances = lastNonConfigurationInstances;当应用配置发生改变时,如屏幕旋转,会导致Activity重建,这个时候会获取上一次保存的mLastNonConfigurationInstances ,并取出其中存储的viewmodestore,最后得到ViewModel,直接从ViewModel中得到数据恢复界面列表。
当activity退出销毁时,通过lifecycle对activity的生命周期监听,如果配置没有发生改变,正常退出,则直接情况ViewModelStore。如果还有对Lifecycle不理解的痛苦可以参考Jetpack之Lifecycle怎么绑定Activity生命周期?
//使用lifecycle对activity生命周期进行监听
getLifecycle().addObserver(new LifecycleEventObserver() {
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
//如果生命周期为onDestory
if (event == Lifecycle.Event.ON_DESTROY) {
// 清除context
mContextAwareHelper.clearAvailableContext();
//如果应用配置没有发生改变
if (!isChangingConfigurations()) {
//清除ViewModelStore中HashMap存储的ViewModel
getViewModelStore().clear();
}
}
}
});
今天的分享就到这里了,相信大家都ViewModel有一定的了解了,关注小编,学习不迷路,欢迎大家一起学习!
留言与评论(共有 0 条评论) “” |