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 通信,解耦且不会内存泄漏。

相关推荐
警醒与鞭策8 小时前
Codex桌面版与Claude桌面版使用设置
android·unity·ai·性能优化
传奇开心果11 小时前
【Compose Multiplatform跨端声明式UI实用技术】第19课:多平台部署与发布
android·kotlin
红尘伴蝶舞11 小时前
加密拦截器让抓包失效,我只能从 4KB 的 logcat 碎片里拼回 JSON
android·kotlin·ai编程
booboosui11 小时前
219 个还是 0 个:读不到微信界面时,我只加不删
android
Android打工仔11 小时前
Compose 中何时该用 padding,何时该用 offset
android·android jetpack
二流小码农11 小时前
HarmonyOS开发助手,0代码让元服务从开发到上架
android·ios·harmonyos
limit007512 小时前
三维 WebGIS 工具选型:加载、样式、分析、交付,一套界面能做完什么
android·前端·web3·安卓·webgl
骑着蜗牛撵大象32713 小时前
让 Codex 值夜班:把告警排查与巡检接成可回滚的自动化链路
android·java·运维·ai·自动化·codex·智能体
2401_8858850413 小时前
芬兰语音通知接口怎样对接?语音提醒接入流程
android·前端·python·php·语音识别
程序猿老A14 小时前
轻量应用服务器怎么用phpcms搭建网站?
android