Jetpack-MVVM-Best-Practice icon indicating copy to clipboard operation
Jetpack-MVVM-Best-Practice copied to clipboard

探讨页面成员变量的保存和恢复

Open hanshengjian opened this issue 5 years ago • 7 comments

@KunMinX 理解了,我看了下配置发生变化时保存的具体对象是viewModelStore,这个对象具体activity的属性,它有个属性mMap,存储了所有的viewModel,通过ViewModelProvider.get()方法时,先获取最后配置变化的viewModelStore,然后从mMap中获取viewModel.理解了这个原理,也有一个小想法,就是viewModelStore是activity的对象,配置发生变化时,因为viewModelStore被保存下来了,所以旧的activity回收不了,感觉也是一个内存泄漏.

Originally posted by @hanshengjian in https://github.com/KunMinX/Jetpack-MVVM-Best-Practice/issues/41#issuecomment-706461028

hanshengjian avatar Oct 10 '20 03:10 hanshengjian

@hanshengjian

非也,配置发生变化时,仍然是基于同一个 Activity 实例,不然就谈不上对已保存状态的恢复了。

对 Activity 自身来说只是重走了一次生命周期流程,具体需结合实际场景理解。

KunMinX avatar Oct 10 '20 07:10 KunMinX

@hanshengjian

非也,配置发生变化时,仍然是基于同一个 Activity 实例,不然就谈不上对已保存状态的恢复了。

对 Activity 自身来说只是重走了一次生命周期流程,具体需结合实际场景理解。

刚开始我也认为是同一个实例(清单文件是默认的launchMode),调试后,发现前后的activity对象的hashCode不一样,说明是两个实例,在配置发生变化时,在对象销毁之前,会存储上一个activity实例的viewModelStore对象,恢复时会取viewModelStore

hanshengjian avatar Oct 10 '20 07:10 hanshengjian

@hanshengjian 很抱歉提供了有出入的解答,刚刚在 onCreate 节点重新测试了一下,确实当旋屏重建时得到的 Activity hashCode 发生了变化。

感谢你对这一现象的观察、思考和分享。

据我过去一年的观察,ViewModel 在 Activity/Fragment 源码中的设计一直在发生变化,所以在对 google 未来的决策背景一无所知的情况下,我暂时无法就未来 ViewModel、Activity/Fragment 源码的设计方向做更多探讨。

Jetpack ViewModel 试图成为当前条件下,解决重量级(例如需要透过 https 网络请求来获取的耗时间、耗电能的)状态的托管和恢复的 “最优解”,所以它并不一定是完美的,也可能存在如你所说的这一缺憾。

所以也可尝试对 demo 做内存泄漏的测试,如该设计的崩溃率能控制在商业角度可接受的比例,我们仍可在权衡利弊后考虑使用 ViewModel 来为我们规避其他更高频、负面影响更大的问题。

KunMinX avatar Oct 10 '20 08:10 KunMinX

后面如果内存泄漏的测试,和你一起在探讨下这个问题.按照你的思路,去理解ViewModel,跳出了MVVM,确实有了更深的理解,ViewModel 对App开发来讲,相比其他的业务开发模式,少操心很多事.也很感谢你写MVVM精讲这篇文章,最近在复习面试,按照这个思路去面试,就像你之前分享出来的小伙伴说的,能把VM说的更加饱满.

hanshengjian avatar Oct 12 '20 08:10 hanshengjian

@hanshengjian 👍

KunMinX avatar Oct 12 '20 09:10 KunMinX

@KunMinX 理解了,我看了下配置发生变化时保存的具体对象是viewModelStore,这个对象具体activity的属性,它有个属性mMap,存储了所有的viewModel,通过ViewModelProvider.get()方法时,先获取最后配置变化的viewModelStore,然后从mMap中获取viewModel.理解了这个原理,也有一个小想法,就是viewModelStore是activity的对象,配置发生变化时,因为viewModelStore被保存下来了,所以旧的activity回收不了,感觉也是一个内存泄漏.

Originally posted by @hanshengjian in #41 (comment)

这里有一个问题,想请教一下,你说的viewModelStore会拥有Activity的属性,从哪里看出来呢? ViewModelStore有mMap,mMap保存ViewModel实例,然而ViewModel并不会有Activity的属性啊 我的理解是,ViewModelStore并没有Activity的属性,也不会导致旧的Activity回收不了

davidgerka avatar Oct 27 '21 03:10 davidgerka

@KunMinX 理解了,我看了下配置发生变化时保存的具体对象是viewModelStore,这个对象具体activity的属性,它有个属性mMap,存储了所有的viewModel,通过ViewModelProvider.get()方法时,先获取最后配置变化的viewModelStore,然后从mMap中获取viewModel.理解了这个原理,也有一个小想法,就是viewModelStore是activity的对象,配置发生变化时,因为viewModelStore被保存下来了,所以旧的activity回收不了,感觉也是一个内存泄漏. Originally posted by @hanshengjian in #41 (comment)

这里有一个问题,想请教一下,你说的viewModelStore会拥有Activity的属性,从哪里看出来呢? ViewModelStore有mMap,mMap保存ViewModel实例,然而ViewModel并不会有Activity的属性啊 我的理解是,ViewModelStore并没有Activity的属性,也不会导致旧的Activity回收不了

赞同你的观点。感觉前面那位老哥,没理明白内存泄露。

JokerChenX avatar Jul 26 '22 06:07 JokerChenX