Android mvvm框架之ViewModel(1),2024Android通用流行框架大全

// 先检查缓存中是否存在

ViewModel viewModel = mViewModelStore.get(key);

if (modelClass.isInstance(viewModel)) {

//noinspection unchecked

return (T) viewModel;

} else {

//noinspection StatementWithEmptyBody

if (viewModel != null) {

// TODO: log a warning.

}

}

// 缓存中没有,通过 Factory 构造

if (mFactory instanceof KeyedFactory) {

viewModel = ((KeyedFactory) (mFactory)).create(key, modelClass);

} else {

viewModel = (mFactory).create(modelClass);

}

// 新实例保存缓存

mViewModelStore.put(key, viewModel);

//noinspection unchecked

return (T) viewModel;

}

3 ViewModel 与配置无关的原理(与宿主 Controller 俱生俱灭)

上一节我们说到,ViewModel 之所以能够与宿主 Controller 保持生命周期一致,是因为存储它的 ViewModelStore 与宿主 Controller 生命周期一致。那么为什么 ViewModelStore 能够保持和 Controller 生命周期一致呢?

这里我们需要先理清 FragmentActivity 和其寄生的 Fragment 的 ViewModelStore 之间的关系:

3.1 ViewModelStore 树

ViewModelStore Tree

如图所示:

  • 每个 ViewModelStore 依附于其宿主 Controller,所以各个 Controller 的 ViewModelStore 组成一个树状的引用关系;

  • 处于顶层的 ViewModelStore 依附于 FragmentActivity,它除了保存用户级的 ViewModel 以外,还保存其儿子 Fragment 的 FragmentManagerViewModel;

  • FragmentManagerViewModel 主要维护两个对象:所属 Fragment 的 ViewModelStore 和其儿子 Fragment 的 FragmentManagerViewModel 的引用,注意图中的红色部分,所有二级及以下的子孙 Fragment 都共用同一个父节点的 Child FragmentManagerModel,这样当父 Fragment 销毁的时候方便一次性清除其所有子 Fragment 共用的 FragmentManagerViewModel;

  • 但是二级及以下的子孙 Fragment 的 ViewModelStore 都是独立的,一个 Fragment 自身的 ViewModel 变化应该不影响其兄弟节点的 ViewModel,所以可以推导出,它们共同的 FragmentManagerViewModel 应该是维护了一个保存各个子 Fragment 的 ViewModelStore 的容器,大家如果细看 FragmentManagerViewModel 的源代码,实际上就是这么做的。

所以,我们看到,处于顶层的 FragmentActivity 的 ViewModelStore 是一个超级 Store,它引用了所有的 ViewModels,包括自身的数据、所有子孙 Fragment 的 ViewModels,只要各子孙 Fragment 不清除自有 ViewModelStore,则所有的数据都维护在这棵 ViewModelStore 树中。

那么在配置发生变化的时候,ViewModelStore 树如何保持不变呢?

3.2 系统级的配置无关支持

将 ViewModelStore 作为配置无关数据进行保持,在 FragmentActivity 中是这么做的:

Retain ViewModelStore in activity

是的,流程就是这么简单,只需要将 ViewModelStore 封装在一个特殊对象中保存并在 FragmentActivity 的 onRetainNonConfigurationInstance() 方法中返回即可:

/**

  • Called by the system, as part of destroying an

  • activity due to a configuration change, when it is known that a new

  • instance will immediately be created for the new configuration. You

  • can return any object you like here, including the activity instance

  • itself, which can later be retrieved by calling

  • {@link #getLastNonConfigurationInstance()} in the new activity

  • instance.

*/

@Override

@Nullable

public final Object onRetainNonConfigurationInstance() {

Object custom = onRetainCustomNonConfigurationInstance();

ViewModelStore viewModelStore = mViewModelStore;

// …省略与原理无关代码

NonConfigurationInstances nci = new NonConfigurationInstances();

nci.custom = custom;

nci.viewModelStore = viewModelStore;

return nci;

}

这样,在顶层源头上就保证了所有 Controller 的 ViewModels 不会在发送配置变化的时候由于 Controller 重建而被销毁。

另外在 Fragment 层中,必须区分 Fragment 实例销毁时到底是因为调用了 onDestroy 还是配置发生了变化,如果是前者则必须清理自身持有的 ViewModelStore,如果是后者则不能清理:

How to clear Fragment's ViewModelStore

如图所示,也说明了 Fragment 的 ViewModel 生命周期与该 Fragment 生命周期是一致的。

// FragmentManagerImpl.moveToState()

//…省略

boolean beingRemoved = f.mRemoving && !f.isInBackStack(); // 是否 destroy,如果只是配置变化,则为 false

if (beingRemoved || mNonConfig.shouldDestroy(f)) {

boolean shouldClear;

if (mHost instanceof ViewModelStoreOwner) {

// 说明这是第一层 Fragment,只要顶层 ViewModelStore 没有清除该 FragmentManagerViewModel 就说明不用清理

shouldClear = mNonConfig.isCleared();

} else if (mHost.getContext() instanceof Activity) {

// 说明是 FragmentActivity 的子孙 Fragment,根据是否是配置变化来判断是否需要清理

Activity activity = (Activity) mHost.getContext();

shouldClear = !activity.isChangingConfigurations();

} else {

shouldClear = true;

}

if (beingRemoved || shouldClear) {

// 只有确实 destroy 了才需要清理

mNonConfig.clearNonConfigState(f);

}

f.performDestroy();

dispatchOnFragmentDestroyed(f, false);

}

//…省略

4 FragmentActivity 中的 ViewModel 生命周期

最后,我们还需要说明一下,FragmentActivity 中的 ViewModel 的生命周期是如何保持与 FragmentActivity 一致的,除了上一节中 FragmentActivity.onRetainNonConfigurationInstance() 中的配置无关保证以外,还需要保证在 Activity 真正销毁的时候其所持有的 ViewModel 也应该被清理。

其代码实现非常简单,只需要观察该 Activity 的 Lifecycle 状态,并在销毁状态时进行清理即可,关于 Lifecycle 我们将用专门的章节进行说明,以下为清理代码:

getLifecycle().addObserver(new LifecycleEventObserver() {

@Override

public void onStateChanged(@NonNull LifecycleOwner source,

@NonNull Lifecycle.Event event) {

if (event == Lifecycle.Event.ON_DESTROY) {

// 观察到 Activity 被销毁

if (!isChangingConfigurations()) {

// 若不是配置变化,则清理

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
img

最后

写到这里也结束了,在文章最后放上一个小小的福利,以下为小编自己在学习过程中整理出的一个学习思路及方向,从事互联网开发,最主要的是要学好技术,而学习技术是一条慢长而艰苦的道路,不能靠一时激情,也不是熬几天几夜就能学好的,必须养成平时努力学习的习惯,更加需要准确的学习方向达到有效的学习效果。

image

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
img
互联网开发,最主要的是要学好技术,而学习技术是一条慢长而艰苦的道路,不能靠一时激情,也不是熬几天几夜就能学好的,必须养成平时努力学习的习惯,更加需要准确的学习方向达到有效的学习效果。**

[外链图片转存中…(img-qNdlThLm-1712604103892)]

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-V0mmyVEn-1712604103892)]

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android MVVM框架是一种基于DataBinding工具实现的框架,它是Android项目框架中的一种,与MVC和MVP框架相对应。MVVM框架的特点是可以在ViewModel中修改View层的展示,而无需通知View层做任何事情。 在使用MVVM框架时,需要创建一个MainActivity和对应的布局xml文件,并在MainActivity中使用DataBindingUtil.setContentView方法将布局文件与Activity进行绑定,然后创建一个ViewModel对象并传入ViewDataBinding参数,实现数据和UI的绑定。 DataBinding是一个实现数据和UI绑定的框架,它可以方便地实现MVVM开发模式。在xml中使用@{}的方式来实现数据的显示,这种方式在Java Web开发中也有类似的应用。123 #### 引用[.reference_title] - *1* *2* [Android 框架系列(二)—— MVVM框架搭建及分析](https://blog.csdn.net/StudyOfAndroid/article/details/108527052)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}} ] [.reference_item] - *3* [Android MVVM架构](https://blog.csdn.net/weixin_53431933/article/details/126372227)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值