内容简介:以默认activity的配置 在屏幕旋转的时候,一般activty都会被重建,以这个情况为例子来说明 Bundle savedInstanceState 和 fragment.setRetainInstance 以及 viewmodel的区别作者github :Bundle savedInstanceState 和 fragment.setRetainInstance 以及 viewmodel(viewModel = ViewModelProviders.of(this).get(UserProfileV
以默认activity的配置 在屏幕旋转的时候,一般activty都会被重建,以这个情况为例子来说明 Bundle savedInstanceState 和 fragment.setRetainInstance 以及 viewmodel的区别
0. 转载请注明原文出处
作者github : github.com/zjw-swun 欢迎相互关注
1. 为什么要把这3个放在一块说
Bundle savedInstanceState 和 fragment.setRetainInstance 以及 viewmodel(viewModel = ViewModelProviders.of(this).get(UserProfileViewModel.class);用法而不是自己new的那种),都具备一种功能,就是当 屏幕旋转的时候( 以默认activity的配置前提),都能保存一些要被销毁掉的activity中的一些数据(如editext文本,以及recyclerView的滑动位置等),那么这3个有什么区别吗,会不会因为我们不知道原理而踩坑,下文给出答案。
2. 结论
-
Bundle savedInstanceState中的数据是由系统进程进行存储的,它能存储的数据容量大小有限(例如intent中如果传输Bundle内容过大会出现异常),但是比如自己app因为手机内存不足而杀掉进程的话,可以能够利用该方式进行数据还原 2.fragment.setRetainInstance以及viewmodel(viewModel = ViewModelProviders.of(this).get(UserProfileViewModel.class);用法而不是自己new的那种)的原理是一样的,都是利用,Activity类的NonConfigurationInstances类在app进程中进行保存的,它能存储数据容量比Bundler savedInstanceState 方式要大,但是比如自己app因为手机内存不足而杀掉进程的话,则不能用该方式进行数据还原
3. 部分源码分析
以下以activity类中NonConfigurationInstances类如何在屏幕旋转的时候( 以默认activity的配置前提)如何存储并恢复NonConfigurationInstances对象为例,剖析原理 以下截图以及截图中的代码api版本为28,运行环境官方api 28的模拟器上 测试代码就不贴了很简单, 先贴一下debug断点列表,有兴趣可以试试,至于如何debug app以及debug系统进程,不知道的朋友可以看一下我另一篇文章 https://www.imooc.com/article/21992 废话不多说 放图
然后看重建activity时候的断点(截图中截的是被杀死的activity 走到ondestroy的时候)
r 和重建时候传入的参数
r
(ActivityThread类中的ActivityClientRecord类型)是同一个对象,看看一下这个ActivityClientRecord类的代码
static final class ActivityClientRecord {
//...不重要参数
Activity.NonConfigurationInstances lastNonConfigurationInstances;
//...不重要参数;
}
复制代码
这就是核心的原理代码了,那么为什么说是存储在app进程中呢,根据断点列表你会发现涉及到一个关键类叫做 ActivityRelaunchItem 这个类
mActivityClientRecord 就是app进程存储的那个
r 了,这个
r 里面包含了
lastNonConfigurationInstances ,当activty切换的时候,系统进程通过binder机制通知app进程的client对象也就是activityThread间接调用
preExecute 方法,进行保存,然后当重建activity的时候再系统进程通过binder机制通知app进程的client对象也就是activityThread(由activityThread.h发送
H.RELAUNCH_ACTIVITY 消息通过handler机制)间接调用
execute 方法 下图是activity重建时候调用
execute
函数调用栈截图
r 中
lastNonConfigurationInstances
再设置给新activity
中间省略的步骤虽然多,但是根据断点列表走下来其实很清楚的。
授人以鱼不如授人以渔
对于如何调试app进程和系统进程, www.imooc.com/article/219… 一文中有具体操作,但是涉及到 binder 类是如何进行 transact 发消息给别的进程以及如何 execTransact 处理别的进程消息 的c++层的原理并没有给出解答,这里推荐一篇博客 blog.csdn.net/innost/arti… 讲解的还算不错。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Web Design Handbook
Baeck, Philippe de 编 / 2009-12 / $ 22.54
This non-technical book brings together contemporary web design's latest and most original creative examples in the areas of services, media, blogs, contacts, links and jobs. It also traces the latest......一起来看看 《Web Design Handbook》 这本书的介绍吧!