首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

一文带你吃透HolderFragment 实现ViewModel的生命周期穿透!

  • 25-04-16 14:41
  • 2667
  • 9031
juejin.cn

在 Android 开发中,若要将 HolderFragment 的数据持久化能力与 ViewModel 的生命周期感知能力结合,可以通过 ViewModel + HolderFragment 混合模式实现更灵活的数据管理。

一、核心设计思想

  • ViewModel 负责管理界面相关的数据,天然支持配置变更时的数据保留。
  • HolderFragment 作为底层容器,通过 setRetainInstance(true) 实现跨 Activity 生命周期的数据持久化(适用于非配置变更场景)。
  • 结合优势:利用 ViewModel 的官方生命周期管理,同时通过 HolderFragment 实现更底层的数据控制。

二、实现步骤

步骤1:创建自定义 ViewModel

定义 ViewModel 子类,封装需要持久化的数据:

kotlin
代码解读
复制代码
class CustomViewModel : ViewModel() { // 普通数据(由 ViewModel 自动保留) var counter: Int = 0 // 需要跨进程重建的复杂数据(通过 HolderFragment 持久化) lateinit var persistentData: SomeComplexData }

步骤 2:实现 HolderFragment 增强层

创建 HolderFragment 作为 ViewModel 的持久化载体:

kotlin
代码解读
复制代码
class HolderFragment : Fragment() { private val viewModelStore = ViewModelStore() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) retainInstance = true // 关键:跨配置变更保留 } // 暴露 ViewModelStore 给宿主 Activity fun getCustomViewModelStore() = viewModelStore override fun onDestroy() { super.onDestroy() viewModelStore.clear() // 清理资源 } }

步骤 3:在 Activity 中绑定 HolderFragment

kotlin
代码解读
复制代码
class MainActivity : AppCompatActivity() { private lateinit var holderFragment: HolderFragment private lateinit var viewModel: CustomViewModel override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 绑定 HolderFragment holderFragment = supportFragmentManager.findFragmentByTag("HolderFragment") as? HolderFragment ?: HolderFragment().also { supportFragmentManager.beginTransaction().add(it, "HolderFragment").commitNow() } // 通过自定义 ViewModelStore 获取 ViewModel val factory = ViewModelProvider.AndroidViewModelFactory(application) viewModel = ViewModelProvider(holderFragment.getCustomViewModelStore(), factory) .get(CustomViewModel::class.java) // 使用 ViewModel 数据 viewModel.counter++ Log.d("MainActivity", "Counter: ${viewModel.counter}") } }

三、关键技术点解析

3.1、ViewModel 生命周期控制

  • 默认行为:ViewModel 在 Activity 配置变更时自动保留,但 Activity 正常销毁(如用户退出)时会被清除。
  • 增强场景:通过 HolderFragment 的 retainInstance=true,让 ViewModel 在 Activity 完全销毁后仍可保留(需谨慎使用,避免内存泄漏)。

3.2、数据持久化范围控制

数据类型存储位置生命周期范围
普通数据(counter)ViewModel配置变更期间保留
复杂数据(persistentData)HolderFragment跨 Activity 销毁/重建(非配置变更)

3.3、双向绑定示例

在 HolderFragment 中保存 ViewModel 的引用:

kotlin
代码解读
复制代码
class HolderFragment : Fragment() { private var retainedViewModel: CustomViewModel? = null fun retainViewModel(viewModel: CustomViewModel) { retainedViewModel = viewModel } fun getRetainedViewModel() = retainedViewModel }

在 Activity 中恢复数据:

kotlin
代码解读
复制代码
override fun onCreate(savedInstanceState: Bundle?) { // 恢复 ViewModel viewModel = holderFragment.getRetainedViewModel() ?: CustomViewModel().also { holderFragment.retainViewModel(it) } }

四、与纯 ViewModel 方案的对比

特性纯 ViewModelViewModel + HolderFragment
配置变更保留✅✅
Activity 完全销毁保留❌✅(通过 HolderFragment)
官方支持✅❌(需自定义实现)
内存泄漏风险低中(需手动管理引用)
适用场景常规页面数据跨页面/跨进程的全局数据

五、高级优化技巧

5.1、自动注入框架

通过 Dagger/Hilt 实现依赖注入:

kotlin
代码解读
复制代码
@Module @InstallIn(FragmentComponent::class) object HolderModule { @Provides fun provideViewModel(holderFragment: HolderFragment): CustomViewModel { return ViewModelProvider(holderFragment.getCustomViewModelStore()).get(CustomViewModel::class.java) } }

5.2、支持 LiveData 观察

在 ViewModel 中集成 LiveData:

kotlin
代码解读
复制代码
class CustomViewModel : ViewModel() { private val _data = MutableLiveData() val data: LiveData = _data fun updateData(newValue: String) { _data.value = newValue } }

5.3、进程死亡恢复

结合 SavedStateHandle 实现数据持久化:

kotlin
代码解读
复制代码
class CustomViewModel(private val state: SavedStateHandle) : ViewModel() { init { state.setSavedStateProvider("data") { Bundle().apply { putString("key", persistentData) } } } }

六、注意事项

  1. 内存泄漏:避免在 HolderFragment 中持有 Activity 强引用,使用 WeakReference。
  2. 线程安全:对 HolderFragment 中的数据访问使用同步锁:
kotlin
代码解读
复制代码
private val lock = Any() fun safeUpdateData() { synchronized(lock) { // 修改共享数据 } }
  1. 生命周期边界:在 onDetach() 中清理不需要的引用:
kotlin
代码解读
复制代码
override fun onDetach() { super.onDetach() retainedViewModel = null }

总结

通过这种混合模式,既可以享受 ViewModel 官方架构组件的便捷性,又能通过 HolderFragment 实现更灵活的数据控制,尤其适合需要 跨 Activity 数据共享 或 长时间数据保留 的复杂场景。

更多分享

  1. Android Jetpack相关面试题分享(一)
  2. Android Jetpack相关面试题分享(二)
  3. Android 架构以及优化相关面试题分享
  4. Android Kotlin协程相关面试题分享
  5. Android 互联网大厂,高频重点面试题集分享(一)
注:本文转载自juejin.cn的QING618的文章"https://juejin.cn/post/7477875236145135642"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2024 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top