viewModel

1、ViewModel 作用

答案

管理页面业务数据、处理业务逻辑;生命周期独立于 Activity/Fragment ,屏幕旋转、配置变更数据不丢失

配合viewModelScope管理协程,自动取消防泄漏;

还可实现多 Fragment 共享通信。

2、ViewModel 生命周期特点

答案

配置变更(旋转屏幕、切语言)不销毁

只有页面真正 finish / 彻底销毁时,ViewModel 才会销毁。

3、为什么屏幕旋转 ViewModel 数据不会丢?

答案

ViewModel 存在 ViewModelStore,不和临时重建的 Activity 绑定;

新 Activity 重建后复用同一个 ViewModel 实例,数据保留。

4、ViewModel 能不能持有 Activity 引用?为什么?

答案

不能

ViewModel 生命周期比 Activity 长,强引用会造成内存泄漏

只能使用 Application Context,不能用 Activity 上下文、View 引用。

5、viewModelScope 是什么?作用

答案

ViewModel 自带协程作用域

绑定 ViewModel 生命周期,ViewModel 销毁时自动取消所有协程,杜绝协程泄漏,不用手动 cancel。

6、ViewModel 会不会内存泄漏?什么情况会泄漏

答案 本身设计防泄漏,人为写错才会漏

  1. 持有 Activity/View 强引用
  2. 内部用 GlobalScope 协程
  3. 静态持有 ViewModel 实例
  4. 网络 / 异步回调持有页面引用

7、ViewModel 与 SavedStateHandle 作用

答案

ViewModel 只能保配置变更数据;

系统杀进程、后台重建数据会丢;

SavedStateHandle 可轻量保存简单数据,进程被杀重建也能恢复。

8、多个 Fragment 怎么通信?

答案

共享同一个 ViewModel,通过 LiveData/Flow 收发数据,解耦不用接口回调。

9、ViewModel 和 onSaveInstanceState 区别

答案

ViewModel:存复杂业务数据、列表对象,配置变更不丢;进程被杀不保 。onSaveInstanceState:只存少量基础类型,进程被杀也能恢复,容量小。

10、ViewModel 为什么不建议放 UI 控件?

答案

违背分离架构;ViewModel 不该持有 View 引用,容易内存泄漏、耦合 UI 层。

面试口述极简总结

ViewModel 用于托管页面数据和业务逻辑,生命周期独立于 View,配置变更数据不重建;不持有 Activity 和 View 引用避免内存泄漏;自带 viewModelScope 自动管理协程生命周期;多 Fragment 可共享通信,搭配 SavedStateHandle 还能处理系统杀进程数据恢复。

11、Fragment的ViewModel如何访问到Activity的ViewModel的数据

1、核心一句话

Fragment 和 Activity 共享同一个 ViewModel 实例 ,Fragment 用所属 Activity 的作用域获取 ViewModel,就能直接拿到 Activity 里的数据。

2、具体原理

  1. ViewModel 是按 ViewModelStoreOwner 来隔离实例的;
  2. 如果 Fragment 获取 ViewModel 时,指定 requireActivity() 作为所有者,就会复用 Activity 级别的同一个 ViewModel
  3. 同一个实例里的数据、LiveData、状态,Fragment 直接可读可观察。

3、Activity 里创建

kotlin

csharp 复制代码
val activityVm: MainViewModel by viewModels()

4、Fragment 里获取(关键)

kotlin

csharp 复制代码
val activityVm: MainViewModel by activityViewModels()

activityViewModels() 本质就是以 宿主 Activity 为 ViewModel 持有者,拿到同一份实例。

Fragment 想要访问 Activity 的 ViewModel 数据,直接用 activityViewModels() 方式获取,会以宿主 Activity 为生命周期所有者,拿到和 Activity 同一个 ViewModel 实例,从而共享里面所有数据和 LiveData,实现 Fragment 与 Activity、Fragment 与 Fragment 解耦通信。

12、多个Fragement怎么共享一个ViewModel的数据?

核心原理

多个 Fragment 共用宿主 Activity 作为 ViewModel 持有者,拿同一个 ViewModel 实例,就能共享数据。

两种实现方式

方式一:用 activityViewModels ()(最简单)

每个 Fragment 里都这样写:

kotlin

csharp 复制代码
val sharedVm: HomeViewModel by activityViewModels()
  • 所有 Fragment 拿到同一个 ViewModel 对象
  • 读写同一个变量、观察同一个 LiveData,自动共享数据
方式二:手动指定宿主 Activity

kotlin

scss 复制代码
val vm = ViewModelProvider(requireActivity())[HomeViewModel::class.java]

效果和 activityViewModels() 完全一样。

为什么能共享

  1. ViewModel 是按 ViewModelStoreOwner 隔离实例
  2. 都以 宿主 Activity 为 Owner,就会拿到同一份 ViewModel;
  3. 同一份实例里的变量、LiveData、状态全部互通。

面试一句话口述

多个 Fragment 通过 activityViewModels 方式获取 ViewModel,统一以宿主 Activity 为生命周期持有者,拿到同一个 ViewModel 实例,通过内部 LiveData 实现数据共享和跨 Fragment 通信,解耦且不会内存泄漏。

相关推荐
爱勇宝6 小时前
我做了一个只用来搜歌词的小 App
android·前端·后端
众少成多积小致巨10 小时前
JNI (Java Native Interface) 技术手册中文参考指南
android·java·c++
Coffeeee16 小时前
如何使用Glide和Coil加载WebP动图
android·kotlin·glide
Kapaseker17 小时前
5 分钟搞懂 Kotlin DSL
android·kotlin
恋猫de小郭17 小时前
AI Agent 开发究竟是啥?如何用 AI 开发 Agent ?深入浅出给你一套概念
android·前端·ai编程
黄林晴18 小时前
Android 17 正式发布!target 37 一大批旧代码直接不能用了
android
Carson带你学Android18 小时前
Android 17 正式发布:AI 终于成了系统能力
android·前端·ai编程
三少爷的鞋18 小时前
当 UseCase 开始长期监听,它可能已经不是 UseCase 了
android
恋猫de小郭1 天前
Android 限制侧载新进展,谷歌联合国内厂商推验证计划
android·前端·flutter
恋猫de小郭1 天前
解读 Android 17 全新内存限制,有没有“豁免”后门?
android·前端·flutter