Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >你真的了解ViewModel的设计思想吗?

你真的了解ViewModel的设计思想吗?

作者头像
Rouse
发布于 2024-01-23 07:52:08
发布于 2024-01-23 07:52:08
36300
代码可运行
举报
文章被收录于专栏:Android补给站Android补给站
运行总次数:0
代码可运行

引言

Android开发中,数据的管理是一个至关重要的问题。随着应用复杂度的增加,我们需要一种能够有效管理数据和处理UI相关逻辑的机制。Android架构组件中的ViewModel应运而生。本文将深入探讨ViewModel的原理,并介绍其高级运用,旨在帮助开发者更好地理解和运用这一组件。

什么是ViewModel?

ViewModel是一种设计模式,它的目标是将UI控制器(Activity、Fragment等)与数据分离,同时保持UI的状态。在Android中,ViewModel通常用于存储和管理与UI相关的数据,以确保这些数据在屏幕旋转或配置更改等情况下不会丢失。

原理解析

ViewModel的原理是基于ViewModelStore类。ViewModelStore类是一个存储ViewModel容器。当UI控制器创建时,系统会为其创建一个ViewModelStore实例。当 UI控制器销毁时,系统会销毁其对应的ViewModelStore实例。

ViewModel在创建时,会将自身注册到其所在的ViewModelStore实例中。当UI控制器销毁时,系统会从其对应的ViewModelStore实例中移除ViewModel

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制

open class ViewModelStore {

    //存储viewmodel
    private val map = mutableMapOf<String, ViewModel>()
    ...

}

// 自动创建
getLifecycle().addObserver(new LifecycleEventObserver() {
    @Override
    public void onStateChanged(@NonNull LifecycleOwner source,
            @NonNull Lifecycle.Event event) {
        ensureViewModelStore();
        getLifecycle().removeObserver(this);
    }
});

// 销毁
getLifecycle().addObserver(new LifecycleEventObserver() {
    @Override
    public void onStateChanged(@NonNull LifecycleOwner source,
            @NonNull Lifecycle.Event event) {
        if (event == Lifecycle.Event.ON_DESTROY) {
            // Clear out the available context
            mContextAwareHelper.clearAvailableContext();
            // And clear the ViewModelStore
            if (!isChangingConfigurations()) {
                getViewModelStore().clear();
            }
            mReportFullyDrawnExecutor.activityDestroyed();
        }
    }
});

所以ViewModelStore的创建与ViewModel的销毁,都与Lifecycle有关,这样就让ViewModel具有以下特性:

  1. 生命周期感知: ViewModel是生命周期感知的,它会自动跟踪UI控制器的生命周期,并在适当的时候进行清理。这意味着我们无需担心内存泄漏或不必要的资源占用。
  2. 持久性存储: ViewModel可以存储大量的数据,并且在配置更改时仍然保持活动。这是通过将ViewModel与UI控制器分离,将其保存在ViewModelStore中实现的。
  3. 数据共享: 多个UI控制器可以共享同一个ViewModel,这为不同组件之间的数据共享提供了便利。这对于在Activity和Fragment之间传递数据非常有用。

为什么需要ViewModelStore

ViewModelStore是用于管理ViewModel实例的生命周期的一种机制。它的存在是为了解决以下问题:

  1. 生命周期一致性:在Android开发中,我们经常遇到配置更改(如屏幕旋转)导致Activity或Fragment被销毁并重新创建的情况。这种情况下,我们希望保持与UI相关的数据的一致性,即使UI重新创建,数据也不会丢失。ViewModelStore通过管理ViewModel实例的生命周期,确保在重新创建UI时,旧的ViewModel实例被正确地销毁,而新的ViewModel实例被正确地创建。
  2. 资源管理:每个ViewModel实例可能持有一些资源,如数据库连接、网络连接等。如果这些资源没有被正确地释放,就会导致内存泄漏和资源浪费。ViewModelStore通过在适当的时机销毁ViewModel实例,确保这些资源可以被正确地释放,避免了内存泄漏和资源浪费。
  3. 数据共享:ViewModelStore允许多个组件共享同一个ViewModel实例。这在某些情况下非常有用,比如一个Activity和它的多个Fragment需要访问和更新相同的数据。通过使用ViewModelStore,这些组件可以共享同一个ViewModel实例,避免了数据的重复加载和同步问题。

简单示例

以下是一个简单的ViewModel示例,演示了如何使用ViewModel来保存和管理数据:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class MyViewModel : ViewModel() {
    private val state = MutableLiveData<String>()

    fun setData(value: String) {
        sate.value = value
    }

    fun getData(): LiveData<String> {
        return state
    }
}

class MyActivity : AppCompatActivity() {

    private val viewModel: MyViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 观察 ViewModel 的数据变化
        viewModel.getData().observe(this, { data ->
            // 更新 UI
        })
    }
}

在上述代码中,ViewModel包含一个MutableLiveData来存储数据。通过setData和getData方法,我们可以设置和获取数据。这个ViewModel将在配置更改时保持活动,确保数据不会丢失。

高级运用

使用SavedStateHandle

SavedStateHandle是一个可用于在配置更改后保持数据的工具。它允许我们将数据与ViewModel关联,以便在应用重新创建时检索。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class MyViewModel(private val savedStateHandle: SavedStateHandle) : ViewModel() {
    private val dataKey = "data_key"

    fun setData(value: String) {
        savedStateHandle.set(dataKey, value)
    }

    fun getData(): String? {
        return savedStateHandle.get(dataKey)
    }
}

处理异步操作

ViewModel可以与协程结合,以处理异步操作。这使得在ViewModel中执行耗时操作成为可能,而不会阻塞UI线程。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class MyViewModel : ViewModel() {
    private val data = MutableLiveData<String>()

    fun fetchData() {
        viewModelScope.launch {
            // 执行耗时操作
            val result = fetchDataFromRepository()
            data.value = result
        }
    }

    fun getData(): LiveData<String> {
        return data
    }
}

使用Factory

ViewModelProvider.Factory用于自定义ViewModel的创建过程,可以传递参数ViewModel的构造函数。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class MyViewModelFactory(private val repository: MyRepository) : ViewModelProvider.Factory {

    override fun <T : ViewModel?> create(modelClass: Class<T>): T {
        if (modelClass.isAssignableFrom(MyViewModel::class.java)) {
            return MyViewModel(repository) as T
        }
        throw IllegalArgumentException("Unknown ViewModel class")
    }
}

注意事项和优化技巧

  • 避免在ViewModel中持有View的引用,以防止内存泄漏。
  • ViewModel的职责限制在处理UI相关的逻辑,不要包含过多的业务逻辑。
  • 谨慎使用SavedStateHandle,避免将大量数据存储在其中导致性能问题。

结语

通过深入理解ViewModel的原理和高级运用,我们可以更好地利用这一强大的架构组件。ViewModel的设计模式和生命周期感知使其成为Android开发中不可或缺的一部分。希望本文能够帮助大家更好地应用和理解ViewModel

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-01-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Android补给站 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Android经典面试题之ViewModel生命周期穿透的3种黑科技实现
大家好,我是稳稳,一个曾经励志用技术改变世界,现在为随时失业做准备的中年奶爸程序员,与你分享生活和学习的点滴。
AntDream
2025/03/07
870
Android经典面试题之ViewModel生命周期穿透的3种黑科技实现
深入理解与运用Android Jetpack ViewModel
在Android开发中,数据与界面的分离一直是一项重要的挑战。为了解决这个问题,Google推出了Android Jetpack组件之一的ViewModel。ViewModel是一种用于管理UI相关数据的架构组件,它能够帮助开发者实现优雅的数据驱动和生命周期管理。本文将深入浅出地介绍ViewModel的使用和原理,带你一步步掌握这个强大的组件。
Rouse
2023/08/31
6580
深入理解与运用Android Jetpack ViewModel
5. Jetpack源码解析---ViewModel基本使用及源码解析
2. Jetpack源码解析—Navigation为什么切换Fragment会重绘?
Hankkin
2019/08/14
8620
Android 面试题:为什么 Activity 都重建了 ViewModel 还存在?—— Jetpack 系列(3)
ViewModel 是 Jetpack 组件中较常用的组件之一,也是实现 MVVM 模式或 MVI 模式的标准组件之一。在这篇文章里,我将与你讨论 ViewModel 实用和面试常见的知识点。如果能帮上忙请务必点赞加关注,这对我非常重要。
用户9995743
2022/09/26
1.3K0
Android 面试题:为什么 Activity 都重建了 ViewModel 还存在?—— Jetpack 系列(3)
ViewModel再问—字节真题
之前我们说过一期ViewModel,但是有读者反映还是有些面试题不会回答,今天就节选一些再来看看 :
码上积木
2020/11/09
1.8K0
Android Jetpack架构组件(三)之ViewModel
我的博客即将同步至 OSCHINA 社区,这是我的 OSCHINA ID:xiangzhihong,邀请大家一同入驻:https://www.oschina.net/sharing-plan/apply
xiangzhihong
2020/12/21
1.4K0
Android Jetpack架构组件(四)之LiveData
LiveData是Jetpack架构组件Lifecycle 库的一部分,是一个可感知生命周期的可观察容器类 (Observable)。与常规的可观察类不同,LiveData 具有生命周期感知能力,这意味着它具有感知应用组件(如 Activity、Fragment 或 Service)的生命周期的能力,并且LiveData仅更新处于活跃生命周期状态的应用组件观察者。
xiangzhihong
2020/12/21
3.5K0
【AAC 系列四】深入理解架构组件:ViewModel
在上一篇 LiveData 原理分析一文中,我们提到了 ViewModel ,它跟 LiveData 配合能够把价值发挥到最大。
程序亦非猿
2019/08/16
9670
【AAC 系列四】深入理解架构组件:ViewModel
【协程】ViewModelScope源码解析
使用协程,相信很多同学已经信手拈来了,但是关于ViewModelScope,可能很多同学在用,但却不知道原理,今天来一探究竟。
yechaoa
2022/06/10
4870
JetPack组件学习ViewModel
1.需要先创建ViewModel类,继承自ViewModel重写onclear方法,使得页面销毁的时候能够走到自定义的onClear方法中
北洋
2022/05/10
6460
JetPack组件学习ViewModel
Android-Jetpack笔记-ViewModel
ViewModel处于数据逻辑层,他的生命周期贯穿整个宿主,如act因屏幕旋转销毁重建时,其依然存活,只有act.finish后,才会自动销毁,因此可以用他来维持宿主的数据状态。现在比较流行的方式是把他当做唯一数据源来驱动UI展示:
Holiday
2020/08/10
7860
Android-Jetpack笔记-ViewModel
Android Jetpack 组件之 ViewModel 详解
ViewModel 具有生命周期意识,会自动存储和管理 UI 相关的数据,即使设备配置发生变化后数据还会存在,我们就不需要在 onSaveInstanceState 保存数据,在 onCreate 中恢复数据了,使用 ViewModel 这部分工作就不需要我们做了,很好地将视图与逻辑分离开来。
子晋
2022/01/18
1.3K0
Android Jetpack 组件之 ViewModel 详解
“终于懂了“系列:Jetpack AAC完整解析(三)ViewModel 完全掌握!
上一篇介绍了Jetpack AAC 的数据处理组件 LiveData,它是使得 数据的更新 能以观察者模式 被observer感知,且此感知只发生在活跃生命周期状态。这篇来介绍与LiveData搭配使用的视图模型组件——ViewModel。
胡飞洋
2021/01/12
1.9K0
“终于懂了“系列:Jetpack AAC完整解析(三)ViewModel 完全掌握!
知识点 | ViewModel 四种集成方式
ViewModel 甫一发布,便成为了 Jetpack 中的核心组件之一。我们在 2019 年做的一份开发者问卷显示,超过 40% 的 Android 开发者已经在自己的应用中使用了 ViewModel。ViewModel 可以将数据层与 UI 分离,而这种架构不仅可以简化 UI 的生命周期的控制,也能让代码获得更好的可测试性。
Android 开发者
2020/05/26
2.6K0
AAC---ViewModel
ViewModel是用来保存并且管理与LifeCycle以及UI相关数据的数据结构。ViewModel允许数据在Configuration改变时(比如屏幕旋转)保存,并且在旋转后恢复。
None_Ling
2018/10/24
8220
AAC---ViewModel
浅谈ViewModel
1 主要功能 Activity、Fragment存活期间的数据存储; bind同一Activity的多个Fragment间数据共享; 独立或与LiveData配合实现代码解耦; 2 使用方法 1) 引入ViewModel 在build.gradle中添加编译lifecycle.extensions module,该module同时包含ViewModel和LiveData: compile('android.arch.lifecycle:extensions:1.0.0') 由于lifecycle.exte
QQ音乐技术团队
2018/02/01
2.7K0
浅谈ViewModel
Android从零开始搭建MVVM架构(3)——ViewModel
ViewModel类是被设计用来以可感知生命周期的方式存储和管理 UI 相关数据,ViewModel中数据会一直存活即使 activity configuration发生变化。
老马的编程之旅
2022/06/22
7540
Android从零开始搭建MVVM架构(3)——ViewModel
开工!今天撸一波Jetpack下的Lifecycle、ViewModel和LiveData
保持基本的手部和呼吸道卫生,坚持安全饮食习惯,并尽可能避免与任何表现出有呼吸道疾病症状(如咳嗽和打喷嚏等)的人密切接触。
Android扫地僧
2020/03/19
1.7K0
开工!今天撸一波Jetpack下的Lifecycle、ViewModel和LiveData
Android Architecture Components 之LiveData, ViewModel
一 入口 阅读源码需要从源码的入口处着手,先看先官方的例子(https://developer.android.com/topic/libraries/architecture/livedata): ViewModel public class NameViewModel extends ViewModel { // Create a LiveData with a String private MutableLiveData<String> mCurrentName; public Muta
用户1127566
2018/06/06
7770
Jetpack组件之ViewModel
对于支持横竖屏切换的应用程序,我们切换横竖屏时,Activity会被重新创建,我们需要考虑数据的存储和恢复。Jetpack为我们提供了ViewModel组件帮我们解决这个问题,ViewModel以注重生命周期的方式存储和管理界面相关的数据。ViewModel独立于配置变化,就算Activity重建,也不会影响ViewModel的生命周期。
八归少年
2022/06/29
7250
Jetpack组件之ViewModel
相关推荐
Android经典面试题之ViewModel生命周期穿透的3种黑科技实现
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验