Activity 状态的保存和恢复
Activity状态保存的两种情况
一、Activity状态保持概念
保存Activity的状态是非常重要的,例如我们在玩一个游戏的时候,突然来了一个电话,这个时候在接听完电话之后我们返回到游戏中,这个时候我们希望游戏还是之前那个进度,或者说发生突发事件,游戏这个应用程序被关闭了,这个时候我们如果再重新打开游戏的话,我们如果还是希望回到之前的进度,我们就需要将其状态保存起来,这样在Activity被摧毁时,我们还能够根据保存的状态回到之前的进度。这就是Activity的状态保存。
二、Activity状态保存的两种情况
当我们的Activity处于stop状态在后台时,系统会自动调用 onSaveInstanceState() 方法,首先我们通过android的官方文档提供的图来看一下具体情况:
1、当由Activity1跳到Activity2时
- 补充1:此时Activity1处于stop状态,其并不会执行ondestory方法,如果此时点击后退按钮,那么Activity1又会重新回到前台界面上,此种情况下,Activity1默认就会保持原来的状态。
- 补充2:当由Activity1跳到Activity2然后又由Activity2跳到Activity3后,当从Activity3返回到Activity2再返回Activity1时,Activity1和Activity2也都会保持原来的状态!但是如果Activity2返回Activity1时是通过Intent跳转的,那返回的Activity1并不是初始时的Activity1,而是新建的另外一个Activity1。
- 补充3:当由Activity1跳到Activity2然后又由Activity2返回Activity1后,Activity2就调用了destory方法,即销毁掉了。所以,当再次由Activity1跳到Activity2时,Activity2也是新建的另一个Activity。
- 补充4:当由Activity1跳到Activity2然后又由Activity2返回Activity1后,Activity2并不会调用 onSaveInstanceState() 方法,因为此时是我们明显是要关闭activity2的,所以系统认为调用 onSaveInstanceState() 是没有必要的。
- 补充5:当由Activity1跳到Activity2后,Activity1会调用 onSaveInstanceState() 方法,但是当又由Activity2返回Activity1后,我们不需要从Activity1的onSaveInstanceState中获取任何状态信息,因为此时Activity1本身就完整的保存了当前的状态。
2、当横竖屏切换时,或者系统杀死了处于stop状态的Activity1的线程
- 当再打开这个Activity时,又会重新创建这个Activity,此时系统会将 onSaveInstanceState 方法中的 Bundle 对象传递给Activity的 onCreate()和 onRestoreInstanceState()方法,使用这两个方法中的任何一个,我们都可以根据之前保存的 Bundle 对象来恢复我们Activity之前的状态。
- 控件的状态都是被默认保存的,我们一般无须关注。
- 我们自己定义的某些状态值,比如,int number,我们可以在onSaveInstanceState中保存起来,这样重建Activity时就可以取出来了。
- 注意,onSaveInstanceState() 方法不能保证一定会被调用,所以我们在onSaveInstanceState() 方法中只能用来保存我们的Activity的临时的状态信息。
- 我们不需要疑惑这个方法和Activity生命周期函数方法的调用时期,例如onPause()方法,当一个Activity处于后台时或者容易受到破坏时,这个方法就会被调用。
示例代码
public class MainActivity extends Activity {
Button btn;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Log.i("bqt", "++++++onCreate");btn = (Button) findViewById(R.id.btn);btn.setText("1=="+new SimpleDateFormat("yyyy.MM.dd HH-mm-ss").format(new Date()));btn.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {//注意,当由1-->2然后由2-->1后,再由1-->2时,2又执行了oncreate方法,说明是重新创建了一个新的2!//但是2并没有执行ondestory方法,说明之前的2并没有被销毁,也即内存中是有两个2的!startActivity(new Intent(MainActivity.this, MainActivity2.class));}});}@Override//按返回键protected void onDestroy() {Log.i("bqt1", "++++++onDestroy");super.onDestroy();}@Overrideprotected void onSaveInstanceState(Bundle outState) {super.onSaveInstanceState(outState);Log.i("bqt1", "++++++onSaveInstanceState");}}
public class MainActivity2 extends Activity {
Button btn;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Log.i("bqt2", "++++++onCreate");btn = (Button) findViewById(R.id.btn);btn.setText("2=="+new SimpleDateFormat("yyyy.MM.dd HH-mm-ss").format(new Date()));btn.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {startActivity(new Intent(MainActivity2.this, MainActivity3.class));}});}@Overrideprotected void onDestroy() {super.onDestroy();Log.i("bqt2", "++++++onDestroy");}@Overrideprotected void onSaveInstanceState(Bundle outState) {super.onSaveInstanceState(outState);Log.i("bqt2", "++++++onSaveInstanceState");}}
public class MainActivity3 extends Activity {
private Button btn;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Log.i("bqt3", "++++++onCreate");btn = (Button) findViewById(R.id.btn);//2-->3-->2后,再由2-->3时肯定是取不出之前保存的状态的,因为那些状态根本不是他保存的!//横竖屏切换时是可以获取之前的状态的!if (savedInstanceState != null) btn.setText(savedInstanceState.getString("key"));else btn.setText("3==" + new SimpleDateFormat("yyyy.MM.dd HH-mm-ss").format(new Date()));btn.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {//注意:此时从3-->1是新建了一个1,他已经不是第一个1了!startActivity(new Intent(MainActivity3.this, MainActivity.class));}});}@Overrideprotected void onDestroy() {super.onDestroy();Log.i("bqt3", "++++++onDestroy");}@Overrideprotected void onSaveInstanceState(Bundle outState) {super.onSaveInstanceState(outState);Log.i("bqt3", "++++++onSaveInstanceState");outState.putString("key", btn.getText().toString());}}
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"android:layout_height="match_parent" ><Buttonandroid:id="@+id/btn"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/hello_world" /></RelativeLayout>
View控件状态的保存
当我们在创建一个Activity对象的时候,我们如果没有重写父类的 onSaveInstanceState()方法,此时我们的一些Activity状态也会通过调用父类Activity的默认的 onSaveInstanceState()方法来保存下来。特别地:父类的onSaveInstanceState()方法会调用布局文件中每一个View对象的相应的 onSaveInstanceState()方法 来保持各自的状态。
在Android的大多数的widget控件都非常好的实现了 onSaveInstanceState()方法,因此我们对这些空间的值的改变都会被自动的保存下来。例如我们的EditText、Checkbox控件,当我们在输入了我们的值后,当Activity被destroy-->recreate的时候,此时我们的值仍然会被保存下来,前提是:如果我们需要保存一个View控件的状态,我们必须通过 android:id 属性给其指定一个唯一的标识符,如果我们没有指定的话,系统则不会保存其状态。
Activity 状态的保存和恢复的更多相关文章
- activity状态的保存和恢复
activity状态的保存和恢复 一.简介 1.保存activity状态 * 保存activity状态,onSaveInstanceState这个方法会自动保存有ID的组件的状态 * 没有ID的组件或 ...
- Android之Activity状态的保存和恢复
系统在某些情况下会调用onSaveInstanceState()和onRestoreInstanceState() 这两个方法来保存和恢复Activity的状态. 一句话:Activity在" ...
- Android开发中Activity状态的保存与恢复
当置于后台的Activity因内存紧张被系统自动回收的时候,再次启动它的话他会重新调用onCretae()从而丢失了之前置于后台前的状态. 这时候就要重写Activity的两个方法来保存和恢复状态,具 ...
- Android中突发情况Activity数据的保存和恢复
Android中突发情况Activity数据的保存和恢复 写在前面:在我们的APP使用的过程中,总有可能出现各种手滑.被压在后台.甚至突然被杀死的情况.所以对APP中一些临时数据或关键持久型数据,就需 ...
- activity状态的保存和保持(onRetainNonConfigurationInstance和getLastNonConfigurationInstanc
本文转载于:http://chengbs.iteye.com/blog/1156167 比较onsaveinstancestate() 与 onretainnonconfigurationinstan ...
- canvas save()和canvas restore()状态的保存和恢复使用方法及实例
canvas.save()用来保存先前状态的 canvas.restore()用来恢复之前保存的状态 注:两种方法必须搭配使用,否则没有效果 <!DOCTYPE html> <htm ...
- Canvas状态的保存与恢复
Canvas的API提供了save()和restore()的方法,用于保存及恢复当前canvas绘图环境的所有属性. save()与restore()方法可以嵌套调用 save()方法将当前绘图环境压 ...
- android activity状态的保存
今天接到一个电面,途中面试官问到一个问题,如果一个activity在后台的时候,因为内存不足可能被杀死,在这之前如果想保存其中的状态数据,比如说客户填的一些信息之类的,该在哪个方法中进行. onSav ...
- Android笔记之自定义的RadioGroup、RadioButton,以及View实例状态的保存与恢复
效果图 activity_main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLay ...
随机推荐
- MPICH2在两台Ubuntu上安装(用mpd做进程管理)
本文在经过大量的实验终于不负众望成功的在两台Ubuntu 12.04上部署MPI的一个小型集群,MPICH2所用版本为mpich2-1.4.1,下载地址:http://www.mcs.anl.gov/ ...
- Linux CentOS6.4下Mysql数据库的安装与配置
一.mysql简介 说到数据库,我们大多想到的是关系型数据库,比如mysql.oracle.sqlserver等等,这些数据库软件在windows上安装都非常的方便,在Linux上如果要安装数据库,咱 ...
- JavaScript 的setAttribute兼容性解决
setAttribute各个浏览器都支持,但在IE7以下版本中,有些属性值还是有差异的,比如 obj.setAttribute("class","classname&qu ...
- jQuery 的ready事件和 JavaScript 的load事件对比
为了理解2个事件的异同,先了解一下HTML文档加载顺序 HTML DOM文档加载步骤 HTML DOM文档加载是按顺序执行的,这与浏览器的渲染方式有关,一般浏览器渲染操作的顺序大致按如下几个步骤 1, ...
- CSS,点击去除虚线边框代码
- mybatis中association的column传入多个参数值
顾名思义,association是联合查询. 在使用association中一定要注意几个问题.文笔不好,白话文描述一下. 1: <association property="fncg ...
- 如何让IIS 8.0支持无后缀图片的访问
进入“MIME类型”模块后,我们点击右侧的“添加”,然后填好文件扩展名和类型值.对于无后缀的图片文件,扩展名只需填写“点”符号即可,类型值根据图片文件实际的扩展名填写.如果是jpeg格式的,那么就填写 ...
- Tinkphp定时发布文章的教程
第一步:在文章表中加一个字段,用来保存定时发布的时间 假定我把这个字段设为 push_time 默认为 0 第二步:写一个方法来检查文章列表,把文章列表到时间的文章改为发布状态 //定时发布文章 pu ...
- 移动H5前端性能优化指南[托尼托尼研究所]
概述 1. PC优化手段在Mobile侧同样适用2. 在Mobile侧我们提出三秒种渲染完成首屏指标3. 基于第二点,首屏加载3秒完成或使用Loading4. 基于联通3G网络平均338KB/s(2. ...
- python学习第十七天 --定制类
何为定制类? Python的class允许定义许多特殊方法,可以让我们非常方便地生成特定的类.在类中应用或者重写python的特殊方法,得到的类,就是定制类. 大家都知道print的用法.见下面例子 ...