Activity的重建(recreate)与恢复
关于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)与恢复相关推荐
- 退出android app时界面残留影响,【Android】App 或 Activity 销毁重建的状态恢复对回调带来的影响...
问题背景 在开发 PassportSDK 时遇到的此类问题,测试反馈说当打开 App 进入登录页面,此时如果切换出去到手机设置页面将App 的定位权限设置为「拒绝授予」,在切换回 App 会发生登录信 ...
- 屏幕旋转导致Activity销毁重建,ViewModel是如何恢复数据的
前言 当屏幕旋转或者切换系统语言时,Activity 生命周期从销毁再重建,但是ViewModel里面的变量值不受到影响,说明ViewModel中的变量在屏幕旋转前进行了存储,在屏幕旋转后又进行了恢复 ...
- Android 面试题:为什么 Activity 都重建了 ViewModel 还存在?
作者:彭旭锐 链接:https://juejin.cn/post/7121998366103306254 前言 ViewModel 是 Jetpack 组件中较常用的组件之一,也是实现 MVVM 模式 ...
- activity状态的保存和恢复
activity状态的保存和恢复 一.简介 1.保存activity状态 * 保存activity状态,onSaveInstanceState这个方法会自动保存有ID的组件的状态 * 没有ID的组件或 ...
- Android学习路线(十三)Activity生命周期——暂停和恢复(Pausing and Resuming )一个Activity
在正常使用应用的过程中,前台的activity在一些时候会被其他的组件遮挡,导致这个activity暂停.举个例子,当一个半透明的activity被打开(例如一个dialog样式的activity), ...
- 模拟Android内存不足 activity回收 值保存 状态恢复
作者简介 微信公众号(高质量文章推送):陈博易 作者:陈博易 声明:本文是个人原创,未经允许请勿转载 商业合作请在微信公众号回复:联系方式 **## 前言 1.我记得我实习的那会,面试官问我关于aci ...
- Android官方开发文档Training系列课程中文版:管理Activity的生命周期之Activity的重建
原文地址:http://android.xsoftlab.net/training/basics/activity-lifecycle/recreating.html#RestoreState 有这么 ...
- Raid磁盘阵列重建后如何恢复原来的数据
[raid数据恢复故障描述] 一台服务器,上层搭建了raid5磁盘阵列,共有5块硬盘在运行用于公司数据的存储,没有备份文件,有一天服务器上有一块硬盘掉线,遂聘请外部运维公司对服务器进行维护,运维公司人 ...
- 微星GT77HX-13VI2023原厂Windows11重建F3一键恢复msirestore功能
微星系列原厂预装出厂Windows10/11恢复系统重建F3小红龙方法教程步骤 1.需要有一个F3恢复母版包 2.需要有原机的swm格式文件 3.最后利用软碟通转换文件格式为iso 4.使用Rufus ...
最新文章
- 阿里云证书 | 套路太深,还是我打开姿势不对?
- 【 FPGA 】控制数码管动态扫描显示的小实验
- 如何最大限度提升虚拟内存性能(组图)
- 798·锣鼓巷·牛街
- 哪里有mysql认证_国内哪个城市可以考mysql认证
- LeetCode 557. 反转字符串中的单词 III(栈)
- python使用pip安装包_python的安装包pip命令基本用法
- 2022焊工(初级)上岗证题目及在线模拟考试
- 驱动精灵w8ndows xp sp2,爱普生Epson TM-T90打印机驱动官方正式版下载,适用于winxp,winvista,win7,win8,win10-驱动精灵...
- 计算机网络和现场总线的区别,现场总线系统的特点和组成
- 我所能做的,就是真实地记录 | 小别手记
- 当自己是个不懂中文,只懂英文的小孩
- 【OpenViNO】模型下载
- 一小时前华为鸿蒙操作系统放出了源代码
- Makefile文件:Makefile介绍
- keystore格式与pfx格式证书互转
- 同人逼死官方系列!基于sddc 协议的SDK框架 sddc_sdk_lib 解析
- android+插入一条短信,android添加一条短信记录
- JAVA之对象的克隆
- 对于ANDROID 5.0及其以上版本WIFI图标上显示感叹号的原因分析及解决方法