深入理解Activity的生命周期和启动模式,就看这一篇【建议收藏】


Activity作为四大组件之首,是使用最为频繁的一种组件。正常情况下,除了Window、Dialog和Toast,我们能见到的界面的确只有Activity。下面主要介绍生命周期和启动模式以及IntentFilter的匹配规则分析。

1. Activity的生命周期全面分析

Activity的生命周期分为两种,一种是典型情况下的生命周期,另一种是异常情况下的生命周期。典型情况下的生命周期是指在有用户参与的情况下,Activity所经过的生命周期的改变;异常情况下的生命周期是指Activity被系统回收或者由于当前设备的Configuration发生改变从而导致Activity被销毁重建。

1.1 典型情况下的生命周期分析

在正常情况下,Activity会经历如下生命周期。

  • onCreate:表示Activity正在被创建,这是生命周期的第一个方法。我们常在这个方法里做一些初始化工作,比如调用setContentView()去加载界面布局资源、初始化Activity所需要的数据。
  • onRestart:表示Activity正在重新启动。一般情况下,当当前Activity从不可见重新变成可见状态时,onRestart就会被调用。
  • onStart:表示Activity正在被启动,此时Activity已经可见但是没有出现在前台,还无法与用户交互
  • onResume:表示Activity已经可见,并且出现在前台开始活动。
  • onPause:表示Activity正在停止,正常情况下,紧接着onStop就会被调用。此时可以做一些存储数据、停止动画等工作,但是注意不能太耗时。因为这会影响到新Activity的显示,onPause必须先执行完,新Activity的onResume才会执行。
  • onStop:表示Activity即将停止,可以做一些回收工作
  • onDestroy:表示Activity即将被销毁。这是生命周期最后一个回调,我们可以做一些回收工作和最终的资源释放
    在这里插入图片描述
    我们都知道onPause和onStop都不能执行耗时的操作,尤其是onPause,这也意味着,我们应当尽量在onStop中做操作,从而使得新Activity尽快显示出来并切换到前台

一些具体情况说明:

  • Activity第一次启动:onCreate --》 onStart --》 onResume
  • 打开新的Activity或者切换到桌面:onPause --》 onStop
  • 再次回到原Activity:onRestart --》 onStart --》 onResume
  • 按下back键回退:onPause --》 onStop --》 onDestroy
  • onCreate和onDestroy是一对,表示Activity的创建和销毁,只能有一次调用。onStart和onStop是一对,可被多次调用。onResume和onPause是一对,可多次被调用。

【一些问题】
Q1:onStart和onResume、onPause和onStop从描述上看差不多,对我们来说有什么实质的不同呢?
A:这两个配对的回调分别表示不同的意义。onStart和onStop是从Activity是否可见的角度来回调的,而onResume和onPause是从Activity是否位于前台这个角度来回调的,除了这种区别,在实际使用中没有其他明显的区别。

Q2:假设当前Activity为A,如果这时用户打开一个新Activity B,那么B的onResume和A的onPause哪个先执行呢?
A:A的onPause先执行,B的onResume后执行。Activity启动过程简单理解,启动Activity的请求会由Instrumentation来处理,然后它通过Binder向AMS发请求,AMS内部维护着一个ActivityStack并负责栈内的Activity的状态同步,AMS通过ActivityThread去同步Activity的状态从而完成生命周期方法的调用。

1.2 异常情况下的生命周期分析

1. 资源相关的系统配置发生改变导致Activity被杀死并重新创建
比如说当前Activity处于竖屏状态,如果突然旋转屏幕,由于系统配置发生了变化,在默认情况下,Activity就会被销毁并且重新创建,当然我们也可以阻止系统重新创建我们的Activity。
在这里插入图片描述
当Activity被重新创建后,系统会调用onRestoreInstanceState,并且把Activity销毁时onSaveInstanceState方法所保存的Bundle对象作为参数同时传递给onRestoreInstanceState和onCreate方法。从时序上来看,onRestoreInstanceState的调用时机在onStart之后。
通常onSaveInstanceState()只适合用于保存一些临时性的状态,而onPause()适合用于数据的持久化保存

Q3:onSaveInstanceState 和 onRestoreInstanceState
A:onSaveInstanceState()的调用遵循一个重要原则,即当系统存在“未经你许可”时销毁了我们的activity的可能时,则onSaveInstanceState()会被系统调用,这是系统的责任,因为它必须要提供一个机会让你保存你的数据(当然你不保存那就随便你了)。如果调用,调用将发生在onPause()或onStop()方法之前。onRestoreInstanceState()被调用的前提是,activity A“确实”被系统销毁了并重建,而如果仅仅是停留在有这种可能性的情况下,则该方法不会被调用,onRestoreInstanceState()在onStart() 和 onResume()之间调用

委托思想:上层委托下层、父容器委托子元素去处理一件事情。比如View的绘制过程、事件分发等都是采用类似的思想。

2. 资源内存不足导致低优先级的Activity被杀死
Activity按照优先级从高到低,可以分为三种:

分类优先级描述
前台Activity正在和用户交互的Activity,优先级最高
可见但非前台Activity对话框导致Activity可见但是位于后台,无法与用户直接交互
后台Activity已经被暂停的Activity,比如执行了onStop,优先级最低

如果一个进程中没有四大组件在执行,那么这个进程将很快被系统杀死。因此,一些后台工作不适合脱离四大组件而独自运行在后台中,这样进程很容易被杀死。比较好的方法是将后台工作放入Service中从而保证进程有一定的优先级,这样就不会轻易被系统杀死。

如果我们不想Activity在某些时候被重新创建,可以给configChanges属性添加值。
在这里插入图片描述
上面表格中的项目很多,但是我们常用的只有locale、orientation和keyboardHidden三个选项。

2. Activity的启动模式

2.1 Activity的LaunchMode

目前Android有四种启动模式:standard、singleTop、singleTask和singleInstance

模式描述
standard标准模式,也是系统的默认模式。每次启动一个Activity都会重新创建一个新的实例,不管这个实例是否已经存在
singleTop栈顶复用模式。如果新Activity已经位于栈顶,那么Activity不会被重新创建,同时onNewIntent方法会被回调
singleTask栈内复用模式。一种单实例模式,只要Activity在栈中存在,那么多次启动此Activity都不会重新创建实例,也会回调onNewIntent
singleInstance单实例模式。它除了具有singleTask的所有特性外,此种模式的Activity只能单独的位于一个任务栈中

TaskAffinity
TaskAffinity可以翻译为任务相关性。这个参数标识了一个Activity所需要的任务栈的名字,默认情况下,所有Activity所需的任务栈的名字为应用的包名。taskAffinity这个属性的值为字符串,且中间必须含有包名分隔符"."。TaskAffinity属性主要和singleTask启动模式或者allowTaskReparenting属性配合使用。任务栈也分为前台任务栈和后台任务栈,后台任务栈中的Activity位于暂停状态,用户可以通过切换将后台任务栈再次调到前台。

Activity指定启动模式的方式:

  1. 通过AndroidManifest为Activity指定启动模式
    在这里插入图片描述
  2. 通过在Intent中设置标志位来为Activity指定启动模式
    在这里插入图片描述

2.2 Activity的Flags

大部分情况下,我们不需要为Activity指定标记位,这里主要介绍一些常用的标记位。

标记位作用
FLAG_ACTIVITY_NEW_TASK为Activity指定“singleTask”启动模式
FLAG_ACTIVITY_SINGLE_TOP为Activity指定“singleTop”启动模式
FLAG_ACTIVITY_CLEAR_TOP清除标记位Activity顶上的Activity
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS该Activity不会出现在历史Activity列表中

3. IntentFilter的匹配规则

我们知道,启动Activity分为两种,显示调用隐式调用。隐式调用需要Intent能够匹配目标组件的IntentFilter中所设置的过滤信息,如果不匹配将无法启动目标Activity。IntentFilter中的过滤信息有action、category、data

在这里插入图片描述

  1. action的匹配规则
    action是一个字符串,action的匹配要求规则是Intent中的action存在且必须和过滤规则中的其中一个action相同。另外,action区分大小写,大小写不同字符串相同的action会匹配失败。
  2. category的匹配规则
    category是一个字符串,category要求Intent可以没有category,但是如果你一旦有category,不管有几个,每个都要能够和过滤规则中的任何一个category相同
  3. data的匹配规则
    在这里插入图片描述
    data由两部分组成,mimeTypeURI。mimeType指媒体类型,比如image/jpeg、audio/mpeg4-generic和video/*等,可以表示图片、文本、视频等不同的媒体格式。URI中包含的数据就比较多了,结构长这样:
    在这里插入图片描述
    再举几个实际点的例子:
    在这里插入图片描述

URI中每个数据的含义:

  • Scheme:URI的模式,比如http、file、content等。如果URI没有指定scheme,那么整个URI的其他参数无效,这也意味着URI无效。
  • Host:URI的主机名,比如www.baidu.com等。如果host未指定,那么整个URI中的其他参数无效,这也意味着URI无效。
  • Port:URI中的端口号,比如80,仅当URI中指定了scheme和host参数的时候port参数才有意义。
  • Path、pathPattern、pathPrefix:这三个参数表述路径信息。

data要求Intent中必须含有data数据,并且data数据能够完全匹配过滤规则中的某一个data

在action和category中,有一类action和category比较重要,它们是:
在这里插入图片描述
这两者共同作用是用来表明这是一个入口Activity并且会出现在系统的应用列表中,少了任何一个都没有实际意义,也无法出现在系统的应用列表中,也就会二者缺一不可。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值