Activity的生命周期和启动模式

Activity的生命周期和启动模式

前言

本文是《Android开发艺术探索》的笔记大纲,方便日后复习和记忆。

Activity典型情况下的生命周期

在这里插入图片描述

  1. onCreate:表示Activity正在被创建,这是生命周期的第一个方法。在这个方法中,我们可以做一些初始化工作,比如调用setContentView去加载界面布局资源、初始化Activity所需数据等。
  2. onRestart:表示Activity正在被重新启动。一般情况下,当当前Activity从不可见变为可见状态时,onRestart就会被调用。这种情形一般是用户行为所导致的,比如用户按Home键切换到桌面或者用户打开了一个新的Activity就会暂停,也就是onPause和onStop被执行了,接着用户又回到了这个Activity,就会出现这种情况。
  3. onStart:表示Activity正在被启动,即将开始,这是Activity已经可见了,但是还没有出现在前台,还无法和用户交互。这个时候其实可以理解为Activity已经显示出来了,但是我们还看不到。
  4. onResume:表示Activity已经可见了,并且出现在前台并开始活动。要注意这和onStart的对比,onStart和onResume都表示Activity已经可见,但是onStart的时候Activity还在后台,onResume的时候Activity才显示到前台。
  5. onPause:表示Activity正在停止,正常情况下,紧接着onStop就会被调用。在特殊情况下,如果这个时候快速地再回到当前Activity,那么onResume会被调用。onPause可以做一些存储数据,停止动画等工作,但是不能太耗时,因为这会影响新Activity的显示,onPause先执行完,新Activity的onResume才会执行。
  6. onStop:表示Activity即将停止,可以做一些稍微重量级的回收工作,同样不能太耗时。
  7. onDestroy:表示Activity即将被销毁,这是Activity生命周期中的最后一个回调,在这里,我们可以做一些回收工作和最终的资源释放。

onStart、onResume和onPause、onStop的区别

onStart和onStop是从Activity是否可见这个角度来回调的,而onResume和onPause是从Activity是否位于前台这个角度来回调的。

Activity A 打开 Activity B 生命周期回调

在这里插入图片描述
A onPause -> B onCreate -> B onStart -> B onResume -> A onStop
(注意:需要Activity A的onPause执行后,新的Activity才会开始创建)

Activity异常情况下的生命周期

情况1:资源相关的系统配置发生改变导致Activity被杀死并重新创建

当我们把一张图片放在drawable目录后,就可以通过Resources去获取这张图片。同时为了兼容不同的设备,我们可能还需要在其他一些目录放置不同的图片,比如drawable-mdpi、drawable-hdpi、drawable-land等。这样,当应用程序启动时,系统就会根据当前设备的情况去加载合适的Resouces资源,比如说横屏手机和竖屏手机会拿到2张不同的图片(设定了landscape或portrait状态下的图片)。比如当前Activiy处于竖屏状态,如果突然旋转屏幕,由于系统配置发生了改变,在默认情况下,Activity就会被销毁并且重新创建,当然我们也可以组织系统重新创建我们的Activity。

在默认情况下,如果我们的Activity不做特殊处理,那么当系统配置发生改变后,Activity就会被销毁并重新创建。
在这里插入图片描述
当系统配置发生改变后,Activity会被销毁,其onPause,onStop,onDestroy均会被调用。由于Activity是在异常情况下终止的:

  • 系统会调用onSaveInstanceState来保存当前Activity的状态,这个方法的调用时机是在onStop之前,它和onPause没有既定的时序关系。
  • 当Activity被重新创建后,系统会调用onRestoreInstanceState,并且把Activity销毁时onSaveInstanceState方法时所保存的Bundle对象作为参数同时传递给onRestoreInstanceState和onCreate方法,onRestoreInstanceState的调用时机在onStart之后。

在onSaveInstanceState和onRestoreInstanceState,系统自动为我们做了一定的恢复工作。当Activity在异常情况下创建时,系统会默认为我们保存当前Activity的视图结构,并且在Activity重启后为我们恢复这些数据,比如文本框中用户输入的数据、ListView滚动的位置,这些View相关的状态系统都能够默认为我们恢复。和Activity一样,每个View都有onSaveInstanceState和onRestoreInstanceState这两个方法

关于保存和恢复View层次结构,系统的工作流程如下:首先Activity被异常终止,Activity会调用onSaveInstanceState去保存数据,同时委托window去保存数据,window再委托它上面的顶层容器(很可能是DecorView)去保存数据,最后顶层容器再去一一通知它的子元素保存数据。(有点类似于事件分发)

情况2:资源内存不足导致低优先级的Activity被杀死

数据存储和恢复过程和情况1完全一致

Activity按照优先级从高到低,可以分为如下三种:

  1. 前台Activity——正在和用户交互的Activity,优先级最高
  2. 可见但非前台Activity——比如Activity中弹出了一个对话框,导致Activity可见但是位于后台无法和用户直接交互。
  3. 后台Activity——已经被暂停的Activity,比如执行了onStop,优先级最低。

Activity的启动模式

Activity的LaunchMode

  1. standard:标准模式,这也是系统的默认模式。每次启动一个Activity都会重新创建一个实例。
  2. singleTop:栈顶复用模式。如果新的Activity已经位于任务栈的栈顶,那么此Activity不会被创建,同时它的onNewIntent将会被回调。如果新的Activity已存在但不位于栈顶,那么新的Activity仍然会被创建。
  3. singleTask:栈内复用模式。在这种模式下,只要Activity在一个栈中存在,那么多次启动此Activity都不会创建新的实例。和singleTop一样,系统会回调其onNewIntent方法。具体一点,当一个具有singleTask模式的Activity A请求启动后,系统首先会寻找是否存在其需要的任务栈,如果不存在该任务栈,则创建该任务栈并且创建Activity A将其压入栈中。如果存在该任务栈,则检查栈中是否存在Activity A,如果存在,将Activity A调至栈顶,并回调其onNewIntent方法,如果不存在,则创建Activity A并将其压入栈中。
  4. singleInstance:单实例模式。这是一种加强的singleTask模式,它除了具有singleTask的所有特性外,还加强了一点,那就是具有此种模式的Activity只能单独地位于任务栈中。

指定Activity的启动模式的方法

第一种方法是在AndroidMenifest中指定启动模式,第二种方式是通过Intent中设置标志位来为Activity指定为启动模式。
2种方式的区别:第二种方式的优先级高于第一种,当两种同时存在时,以第二种方式为准。其次,这两种方式的限定范围上有所不同,第一种方法无法直接指定FLAG_ACTIVITY_CLEAR_TOP标识,而第二种方式无法为Activity指定singleInstance模式

IntentFilter的匹配规则

启动Activity分为2种:显式调用和隐式调用。显式调用的优先级高于隐式调用。隐式调用需要Intent能够匹配目标组件的IntentFilter中所设置的过滤信息,如果不匹配则无法启动Activity。

为了匹配过滤列表,需要同时匹配过滤列表中的action、category、data信息,否则匹配失败。

一个Activity可以有多个intent-filter,一个intent只要能匹配一组intent-filter即可成功启动对应的activity。

action的匹配规则

action的匹配要求intent中的action存在且必须和过滤规则中的其中一个相同。

category的匹配规则

  1. category的匹配要求intent中如果含有category,那么所有的category都必须和过滤规则中的其中一个category相同。
  2. intent中可以没有category,如果没有category,intent依旧可以匹配成功。
  3. 系统在用startActivity或者startActivityForResult的时候会默认为intent加上“android.intent.category.DEFAULT”。为了activity能够接收隐式调用,需要在intent-filter中添加“android.intent.category.DEFAULT”。

action和category的不同

action是必须有且和其中intent-filter中一个action相同。
category可以没有,但是如果有它必须和intent-filter中的一个相同。

data的匹配规则

如果过滤规则中定义了data,那么Intent中也要定义可匹配的data。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值