关于Activity的重建我们可以从以下三个方面去了解:

Activity会出现重建的三种情况:

1. 系统内存不足:android系统会杀死一个进程,在系统需要释放内存的时候,而位于进程内的activity就会被销毁。在用户重新回到这个Activity的时候,这个Activity 就会被重建。

2. Configuration Change(Activity横竖屏切换,进入多窗口模式):在横竖屏切换时,系统为了调整布局适应新的配置,在默认情况下会重建Activity。

3. 调用Activity的oncreate()方法:主题切换时可以调用oncreate重建Activity使新的主题生效。

Activity在重建时的状态变化:

首先我们通过一段简单代码来看一下重建过程Activity的状态:

public class LifeCycleActivity extends AppCompatActivity {private static final String TAG = LifeCycleActivity.class.getName();private static final String KEY_TEST = "test";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_life_cycle);TextView tvContent = findViewById(R.id.tv_content);if (savedInstanceState == null) {Log.i(TAG, " ---> first time onCreate");} else {Log.i(TAG, " ---> recreate");String test = savedInstanceState.getString(KEY_TEST);tvContent.setText(test);}findViewById(R.id.btn_start).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {recreate();}});}@Overrideprotected void onStart() {super.onStart();Log.i(TAG, " ---> onStart");}@Overrideprotected void onResume() {super.onResume();Log.i(TAG, " ---> onResume");}@Overrideprotected void onPause() {super.onPause();Log.i(TAG, " ---> onPause");}@Overrideprotected void onStop() {super.onStop();Log.i(TAG, " ---> onStop");}@Overrideprotected void onDestroy() {super.onDestroy();Log.i(TAG, " ---> onDestory");}@Overrideprotected void onRestart() {super.onRestart();Log.i(TAG, " ---> onRestart");}@Overrideprotected void onSaveInstanceState(Bundle outState) {super.onSaveInstanceState(outState);outState.putString(KEY_TEST, "testing");Log.i(TAG," ---> onSaveInstanceState");}@Overrideprotected void onRestoreInstanceState(Bundle savedInstanceState) {super.onRestoreInstanceState(savedInstanceState);String test = savedInstanceState.getString(KEY_TEST);Log.i(TAG, " ---> onRestoreInstanceState");}
}

App运行之后切换横竖屏,通过上面代码实验得到的结果是:

I/com.zj.activitylifecycle.LifeCycleActivity:  ---> first time onCreate
I/com.zj.activitylifecycle.LifeCycleActivity:  ---> onStart
I/com.zj.activitylifecycle.LifeCycleActivity:  ---> onResume
I/com.zj.activitylifecycle.LifeCycleActivity:  ---> onPause
I/com.zj.activitylifecycle.LifeCycleActivity:  ---> onSaveInstanceState
I/com.zj.activitylifecycle.LifeCycleActivity:  ---> onStop
I/com.zj.activitylifecycle.LifeCycleActivity:  ---> onDestory
I/com.zj.activitylifecycle.LifeCycleActivity:  ---> recreate
I/com.zj.activitylifecycle.LifeCycleActivity:  ---> onStart
I/com.zj.activitylifecycle.LifeCycleActivity:  ---> onRestoreInstanceState
I/com.zj.activitylifecycle.LifeCycleActivity:  ---> onResume
在进入paused状态之后,会调用onSaveInstanceState去保存需要的数据状态,在重建的时候可以在onCreate和onRestoreInstanceState中的参数去获取销毁前保存的数据。

Activity的状态恢复

在一些场景下你的Activity是被正常的销毁,当用户按下返回键,或者Activity内部调用finish()方法,在用户和系统的观念中这个Activity的实例是已经不再需要了。在这些场景下Activity的销毁,你不需要做其他额外的工作。但是如果系统销毁Activity是由于系统的限制(configuration和memory pressure), 这种情况下为了保持用户用户体验,我们需要在用户回到Activity时恢复Activity的状态。这种情况下,尽管Activity的实例已经消失,但是系统会记住Activity的实例曾经存在过。如果用户尝试重新回到Activity的时候,系统会使用Activity在被销毁时保存的状态和数据去创建一个新的Activity实例。

系统用来恢复之前的状态而保存的数据叫做instance state,是存储在Bundle中的键值对集合。默认情况下,系统使用Bundle来存储layout中View的状态(例如在EditText中输入的信息),确保Activity重建时能恢复到之前的状态。你也可以用来存储一些你想要在重建时恢复的信息,例如一些成员变量的值和用户的进度信息。

ps:为了确保系统能够恢复你Activity中View的状态,每一个View都需要有一个独特的id(通过 android:id 属性定义)。

但是Bundle不适合用来保存大量的数据,因为数据在保存时需要在主线程中序列化,会消耗系统内存。如果有比较多的数据需要保存时可以结合本地存储。

View的状态系统会自动保存我们不需要做额外的事情,但是你有其他数据需要存储时可以重写onSaveInstanceState方法:

@Override
protected void onSaveInstanceState(Bundle outState) {super.onSaveInstanceState(outState);outState.putString(KEY_TEST, "testing");Log.i(TAG," ---> onSaveInstanceState");
}

数据在onCreate或onRestoreInstanceState中恢复:

@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_life_cycle);TextView tvContent = findViewById(R.id.tv_content);if (savedInstanceState == null) {Log.i(TAG, " ---> first time onCreate");} else {Log.i(TAG, "recreate");String test = savedInstanceState.getString(KEY_TEST);tvContent.setText(test);}findViewById(R.id.btn_start).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {recreate();
//                Intent intent = new Intent(LifeCycleActivity.this, SecondActivity.class);
//                startActivity(intent);}});}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {super.onRestoreInstanceState(savedInstanceState);String test = savedInstanceState.getString(KEY_TEST);Log.i(TAG, "onRestoreInstanceState");
}

onSaveInstance方法并不是每次都会在onPause之后被调用,如果Activity是被明确的close(用户点击返回按钮)或者调用finish时,onSaveInstanceState不会被调用。

如果需要持久化数据,如保存到preference或database,最佳选择是Activity在前台的时候去保存,如果没有这样的机会你可以在onStop方法中去保存。

Activity的重建(recreate)与恢复相关推荐

  1. 退出android app时界面残留影响,【Android】App 或 Activity 销毁重建的状态恢复对回调带来的影响...

    问题背景 在开发 PassportSDK 时遇到的此类问题,测试反馈说当打开 App 进入登录页面,此时如果切换出去到手机设置页面将App 的定位权限设置为「拒绝授予」,在切换回 App 会发生登录信 ...

  2. 屏幕旋转导致Activity销毁重建,ViewModel是如何恢复数据的

    前言 当屏幕旋转或者切换系统语言时,Activity 生命周期从销毁再重建,但是ViewModel里面的变量值不受到影响,说明ViewModel中的变量在屏幕旋转前进行了存储,在屏幕旋转后又进行了恢复 ...

  3. Android 面试题:为什么 Activity 都重建了 ViewModel 还存在?

    作者:彭旭锐 链接:https://juejin.cn/post/7121998366103306254 前言 ViewModel 是 Jetpack 组件中较常用的组件之一,也是实现 MVVM 模式 ...

  4. activity状态的保存和恢复

    activity状态的保存和恢复 一.简介 1.保存activity状态 * 保存activity状态,onSaveInstanceState这个方法会自动保存有ID的组件的状态 * 没有ID的组件或 ...

  5. Android学习路线(十三)Activity生命周期——暂停和恢复(Pausing and Resuming )一个Activity

    在正常使用应用的过程中,前台的activity在一些时候会被其他的组件遮挡,导致这个activity暂停.举个例子,当一个半透明的activity被打开(例如一个dialog样式的activity), ...

  6. 模拟Android内存不足 activity回收 值保存 状态恢复

    作者简介 微信公众号(高质量文章推送):陈博易 作者:陈博易 声明:本文是个人原创,未经允许请勿转载 商业合作请在微信公众号回复:联系方式 **## 前言 1.我记得我实习的那会,面试官问我关于aci ...

  7. Android官方开发文档Training系列课程中文版:管理Activity的生命周期之Activity的重建

    原文地址:http://android.xsoftlab.net/training/basics/activity-lifecycle/recreating.html#RestoreState 有这么 ...

  8. Raid磁盘阵列重建后如何恢复原来的数据

    [raid数据恢复故障描述] 一台服务器,上层搭建了raid5磁盘阵列,共有5块硬盘在运行用于公司数据的存储,没有备份文件,有一天服务器上有一块硬盘掉线,遂聘请外部运维公司对服务器进行维护,运维公司人 ...

  9. 微星GT77HX-13VI2023原厂Windows11重建F3一键恢复msirestore功能

    微星系列原厂预装出厂Windows10/11恢复系统重建F3小红龙方法教程步骤 1.需要有一个F3恢复母版包 2.需要有原机的swm格式文件 3.最后利用软碟通转换文件格式为iso 4.使用Rufus ...

最新文章

  1. 阿里云证书 | 套路太深,还是我打开姿势不对?
  2. 【 FPGA 】控制数码管动态扫描显示的小实验
  3. 如何最大限度提升虚拟内存性能(组图)
  4. 798·锣鼓巷·牛街
  5. 哪里有mysql认证_国内哪个城市可以考mysql认证
  6. LeetCode 557. 反转字符串中的单词 III(栈)
  7. python使用pip安装包_python的安装包pip命令基本用法
  8. 2022焊工(初级)上岗证题目及在线模拟考试
  9. 驱动精灵w8ndows xp sp2,爱普生Epson TM-T90打印机驱动官方正式版下载,适用于winxp,winvista,win7,win8,win10-驱动精灵...
  10. 计算机网络和现场总线的区别,现场总线系统的特点和组成
  11. 我所能做的,就是真实地记录 | 小别手记
  12. 当自己是个不懂中文,只懂英文的小孩
  13. 【OpenViNO】模型下载
  14. 一小时前华为鸿蒙操作系统放出了源代码
  15. Makefile文件:Makefile介绍
  16. keystore格式与pfx格式证书互转
  17. 同人逼死官方系列!基于sddc 协议的SDK框架 sddc_sdk_lib 解析
  18. android+插入一条短信,android添加一条短信记录
  19. JAVA之对象的克隆
  20. 对于ANDROID 5.0及其以上版本WIFI图标上显示感叹号的原因分析及解决方法

热门文章

  1. QSV是什么格式qsv格式怎么转换为MP4
  2. Minimum supported Gradle version is 4 6 Current version is 4 4 Pleas
  3. 【Netty】利用Netty实现心跳检测和重连机制
  4. 利用python模块pandas获取网页表格,并保存为excel
  5. 时尚创意孟菲斯风格PPT模板
  6. 【附源码】计算机毕业设计SSM闲置物品交易平台
  7. 前端小作业~二维码动画
  8. React的服务器渲染和客户端渲染
  9. BZOJ 5252 林克卡特树 —— 树形dp + wqs二分
  10. 惠普电脑u盘重装系统步骤_解决惠普电脑u盘重装系统win10教程