android Activity生命周期(设备旋转、数据恢复等)与启动模式

时间:2022-09-09 18:01:45

博客逐步迁移至 极客兔兔的小站

1.Activity生命周期

    接下来将介绍 Android Activity(四大组件之一) 的生命周期, 包含运行、暂停和停止三种状态,onCreate、onStart、onResume、onPause、onStop、onDestroy六种系统调用方法。

1.1 Activity生命周期简介与测试

android Activity生命周期(设备旋转、数据恢复等)与启动模式

    如图所示,Activity实例可以在生命周期状态发生关键性转换时完成某些工作。

  • onCreate() 创建,该方法是最常被覆盖的方法,第一次创建实例时调用, 一般用来完成实例创建的初始化操作,包括实例化组件,设置监听器,访问外部模型数据等。
  • onStart() 开始,当Activity处于可见状态的时候就会调用onStart方法,包括创建完实例显示,或者从其他活动切换到活动时调用。
  • onResume() 准备,当Activity获得用户焦点时调用。
  • onPause 暂停,当Activity准备调用或者恢复另一个活动时调用,失去焦点时,例如启动一个Dialog调用。该方法可以释放一些消耗CPU的资源,保存一些关键数据,但是执行速度要快,否则影响新的栈顶活动使用。
  • onStop 停止,完全不可见时调用。例如成功启动了另外一个活动,该活动离开栈顶不可见。启动Dialog不会执行该方法。
  • onDestroy 销毁,这个方法在活动销毁时调用。
// 可以使用以下方法进行测试。
public class MainActivity extends Activity { private String TAG = "MainActivity"; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG,"Create");
} @Override
protected void onStart() {
super.onStart();
Log.d(TAG, "Start");
} @Override
protected void onResume() {
super.onResume();
Log.d(TAG, "Resume");
} @Override
protected void onPause() {
super.onPause();
Log.d(TAG, "Pause");
} @Override
protected void onStop() {
super.onStop();
Log.d(TAG, "Stop");
} @Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "Destroy");
}
}

1.2 设备旋转时的生命周期与数据恢复

android Activity生命周期(设备旋转、数据恢复等)与启动模式

    使用上面的日志打印测试方法发现, 设备旋转时生命周期如图所示,即设备旋转时,当前活动实例会被系统销毁,然后创建一个新的实例。

    因为旋转设备会改变设备配置(device configuration),设备配置包括屏幕的方向、密度、尺寸、键盘类型、底座模式等,为匹配不同的设备,可以使用不同的布局文件,这和Web开发中 针对不同宽度的屏幕选择不同CSS样式异曲同工,如何创建不同布局适配不同配置设备不在本文讨论之列。

    设备旋转时,临时数据会丢失。例如你使用了一个变量记录了用户点击了多少次按钮,设备旋转之后,Activity重新创建,这个变量就被初始化了,这里可以使用Bundle对象来恢复。保存数据可以覆盖onSaveInstanceState()方法。

    例如下面的代码,按3次按钮,旋转屏幕后,将打印出saved currentPage:3 init mCurrentPage:0,点击次数存在了Bundle对象中,并在onCreate()中获取到。

/*
* onSaveInstanceState()通常在onPause、onStop、onDestroy前由系统调用
* onCreate()传入的参数savedInstanceState可获取保存的变量
*/
public class MainActivity extends Activity { private static final String KEY = "currentPage";
private static final String TAG = "MainActivity";
private Integer mCurrentPage = 0; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mCurrentPage += 1;
}
});
if(savedInstanceState != null){
// 打印使用Bundle保存的currentPage信息
Log.d(TAG,"saved currentPage: " + savedInstanceState.getInt(KEY,0));
// 打印新建活动mCurrentPage的值,总为0
Log.d(TAG,"init mCurrentPage: " + mCurrentPage);
// ... update code
}
} @Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// 使用key-value对的方式存储临时变量
outState.putInt(KEY, mCurrentPage);
}
}

1.3 Activity暂存与Activity记录

    当系统回收内存时,处于Pause、Stop状态的Activity可能被销毁,此时系统会调用onSaveInstanceState(),用户数据被存储在Bundle对象中,系统将Bundle对象放入Activity记录,可以将这种状态理解为Activity的暂存状态(无实例有记录)。

    Activity暂存后,当前活动不复存在,Activity记录可帮助用户返回应用时活动的快速恢复,提供一个好的用户体验。但是当用户按了后退键,系统会彻底销毁当前活动,Activity记录同时被清除,系统重启也会被清除该记录。

2.Activity启动模式

2.1 standard(默认)

     standard是活动默认的启动模式,Android是使用返回栈来管理活动的,所谓栈就是先进后出,后进先出。该模式下,每启动一个新的活动,就会在返回栈中入栈,并处于栈顶的位置(即用户当前见到的活动)。系统不会 检查该活动的实例已经在返回栈中存在,每次启动都新建一个。当前返回栈为A->B(B为栈顶),新建活动B, 返回栈变为A->B->B。

2.2 singleTop

    standard模式有时并不合理,比如活动实例已经在栈顶了,再次启动时还需再创建一个实例, 这会造成资源的浪费。singleTop模式下,如果当前栈顶已经是该活动实例,则认为可以直接使用,而不再创建新的活动。当前返回栈为A->B(B为栈顶),新建活动B, 返回栈仍为A->B。

<!--AndroidManifest.xml-->
<!--设置方式,launchMode -->
<activity android:name=".MainActivity"
android:launchMode="singleTop"
android:label="AndroidDialog">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>

2.3 singleTask

    singleTop模式可以避免重复创建栈顶活动的问题,但是如果启动活动不在栈顶,而之前已经创建过,还是会重复创建。例如A->B->C,当前已有三个活动A、B、C,C位于栈顶,再创建B,返回栈变为A->B->C->B(另一个实例)。singleTask模式可以让返回栈中每个活动只存在一个实例,如果发现当前需要启动活动已经在栈中,则直接使用,但是该活动之上的所有活动全部出栈;如没有发现,则创建新的实例。例如A->B->C,如此时创建活动B,则返回栈变为A->B(B存在,使用B,C出栈);若此时创建活动D,则返回栈变为A->B->C->D

2.4 singleInstance

    singleInstance模式是四种启动模式中最复杂的,不同于上述三种模式,指定为singleInstance模式的活动会启动一个新的返回栈来管理这个活动。例如当前有活动A、B、C,活动A、C为默认启动模式,B指定为singleInstance模式,首先新建A,A活动页面启动B,B启动C,此时的返回栈并不是A->B->C,而是存在2个返回栈,一个是A->C,另一个是B。此时按下BACK键返回,将从C返回到A,再按一次,A返回到B,按第三次,程序退出。即返回时,先清空栈A->C,再清空栈B。

    singleInstance模式有什么应用场景呢?例如当前程序中某个活动允许其他活动调用,如果想多个程序共享该活动的一个实例A,那么每一个程序都有一个返回栈,若使用前3种模式,该活动入栈时必然创建新的实例,无法实现实例共享。singleInstance能很好地解决这个问题。

android Activity生命周期(设备旋转、数据恢复等)与启动模式的更多相关文章

  1. Android Activity生命周期详讲

    管理 Activity 生命周期 通过实现回调方法管理 Activity 的生命周期对开发强大而又灵活的应用至关重要. Activity 的生命周期会直接受到 Activity 与其他 Activit ...

  2. xamarin Android activity生命周期详解

    学Xamarin我为什么要写这样一篇关于Android 的activity生命周期的文章 已经学Xamarin android有一段时间了,现在想起当初Xamarin也走了不少的弯路.当然Xamari ...

  3. Android——Activity生命周期(转)

    Activity生命周期   子曰:溫故而知新,可以為師矣.<論語> 学习技术也一样,对于技术文档或者经典的技术书籍来说,指望看一遍就完全掌握,那基本不大可能,所以我们需要经常回过头再仔细 ...

  4. Android Activity生命周期的几个问题

      每一个Android开发者都应该知道,android系统有四个重要的基本组件,即Activity(活动).Service(服务).Broadcast Receive(广播接收器)和Content ...

  5. &lbrack;转&rsqb;&colon; 两分钟彻底让你明白Android Activity生命周期&lpar;图文&rpar;&excl;

    转自:http://blog.csdn.net/android_tutor/article/details/5772285 大家好,今天给大家详解一下Android中Activity的生命周期,我在前 ...

  6. Android Activity生命周期

    从android api文档摘抄出来的activity生命周期图如下: Activity有如下四种状态 a.活动状态  activity处于屏幕前台,获取到了焦点可以和用户进行交互,同一时刻只有一个a ...

  7. Android Activity生命周期以及Fragment生命周期的区别与分析

    Android Fragment生命周期图: Activity生命周期图: 对照图: Fragment生命周期分析: 1. 当一个fragment被创建的时候,它会经历以下状态. onAttach() ...

  8. Android Activity 生命周期详解

    学习android开发这么久对于activity的生命周期还没有仔细思考过,所以,我大致的把这些东西整理一下,希望通过这使自己理解的更透彻点吧! 首先看一下Activity生命周期图和它的的四个阶段 ...

  9. android --Activity生命周期具体解释

    一. 再探Activity生命周期 为了研究activity的生命周期,简单測试代码例如以下. package com.example.testactivity; import android.app ...

随机推荐

  1. Object-C目录

    Object学习目录: 1.OC概述 2.OC第一个应用程序 3.OC之类和对象(属性.方法,点语法) 4.OC之类的扩充(self,super关键字.继承.构造函数等)   5.OC之分类Categ ...

  2. Win7如何显示&sol;隐藏Administrator账号

    为了保证安全,windows7的administrator账户默认在登录时是不显示的. 在登录页面显示administrator账户的方法: 1. 选择"开始"菜单->&qu ...

  3. 开发框架Data Abstract和Hydra发布版本Winter 2013

    Data Abstract Winter 2013即Data Abstract Version 7.0.73 (Build .1111),Winter 2013版对Data Abstract继续做了以 ...

  4. 复旦高等代数 I(15级)思考题

    1.证明: 第三类分块初等变换是若干个第三类初等变换的复合. 特别地, 第三类分块初等变换不改变行列式的值. 2.设 $n\,(n\geq 2)$ 阶方阵 $A=(a_{ij}(x))$, 其中每个元 ...

  5. 【转】photoshop CS2安装激活破解教程

    原文网址:http://www.16xx8.com/photoshop/jiaocheng/109348_all.html photoshop CS2安装教程:(本页介绍如何安装CS2软件,如果你安装 ...

  6. &lbrack;BZOJ 1033&rsqb; &lbrack;ZJOI2008&rsqb; 杀蚂蚁antbuster 【模拟!】

    题目链接: BZOJ - 1033 题目分析 模拟!纯粹按照题目描述模拟! 这是一道喜闻乐见的经典模拟题! 我一共写了2遍,Debug 历时2天的所有晚自习 ... 时间超过 8h ... 我真是太弱 ...

  7. AutoLayout没有相对比例布局

    怎么实现相对比例布局 比如我一个控件相对上边距的位置在整个屏幕的比例 可以用stack view来管理相对布局

  8. alsa声卡分析alsa-utils调用过程(一)-tinyplay

    如何分析tinyplay 播放音频和tinymix的过程?需要相应的工具来支持追查: 一.分析tinyplay和tinymix: 1.1 利用strace工具: strace -o tinyplay. ...

  9. 利用java代码生成keyStore

    在前面的章节中介绍了如何利用KeyTool工具生成keyStore:传送门. 但是很多时候,在javaWeb项目中,比如给每个用户加上独特的数字签名,那么我们需要在创建用户的时候,给其生成独一无二的k ...

  10. php 连接数据库

    连接数据库 <?php $con = mysql_connect("localhost","root","root"); if (!$ ...