Activity生命周期、启动模式、IntentFilter详解

生命周期

1、各状态描述
onCreate:
表示Activity开始创建。一般在里面做一些数据初始化的操作;

onStart:
表示Activity正在启动,即将进入前台。这个时候Activity已经创建出来了,但是还没有进入前台,无法与用户交互;

onRestart:
表示Activity正在重新启动。从不可见状态(onStop状态)重新回到可见状态时,会调用回调这个方法;

onResume:
表示Activity已经进入前台,能够与用户进行交互;

onPause:
表示Activity即将停止。从完全可见状态变为部分可见状态时会回调这个方法;

onStop:
表示Activity正在停止。从部分可见状态变为不可见状态(从前台到后台)时,会回调这个方法;

onDestroy:
表示Activity正在销毁。这是Activity生命周期的最后一个方法,一般在这个方法里做一些资源回收的工作;

注:
onStart和onStop是从Activity是否可见这个角度来回调的,onResume和onPause是从Activity是否位于前台这个角度来回调的,除了这个区别,实际使用过程中没有其它明显区别。

2、正常情况生命周期详解
启动一个Activity:
onCreate - onStart - onResume;

从Activity回到Home:
onPause - onStop;

从旧Activity启动新Activity:
旧Activity执行onPause - onStop完成后, 新Activity执行onCreate - onStart - onResume。如果新Activity使用透明背景,旧Activity不会执行onStop方法;

从新Activity返回旧Activity:
新Activity执行onPause - onStop - onDestroy,旧Activity执行onRestart - onStart - onResume。如果新Activity使用透明背景,旧Activity不会执行onRestart和onStart方法,直接onResume;

3、两种异常情况
① 内存不足导致Activity被杀死,然后再恢复;
② 配置改变导致Activity被杀死(比如屏幕方向改变),然后重新恢复;

这两种异常情况下,Activity被杀死的回调顺序是:
onPause和onSaveInstanceState(这两个方法调用没有固定顺序) - onstop - onDestroy;

Activity重新恢复的回调顺序是:
onCreate - onStart - onResume和onRestoreInstanceState(这两个方法没有固定顺序)

对于第二种异常情况,可以通过在manifest中设置Activity标签下的configChanges属性,来设置其是否重启Activity。比如设置”android:configChanges = “orientation”后,屏幕方向改变时,不会重启Activity,而是回调Activity的onConfigurationChanged()方法。

4、数据保存
Activity被杀死时,有两种数据需要保存,一种是控件的状态,一种是用户产生的数据。

对于控件的状态,系统已经帮我们自动保存了。Activity回调onSaveInstanceState方法,这个方法里,会委托Window去保存数据,Window又委托最顶层的DecorView,DecorView再通知其子控件调用onSaveInstanceState保存数据。

对于用户产生的数据,需要我们重写onSaveInstanceState,把需要保存的数据存入Bundle中,然后再重启Acitvity时,这个Bundle会同时传入onCreate和ononRestoreInstanceState中,我们在这两个方法里都能获取到。

Activity启动模式

Activity的启动特性有两种:一种是“是否重新创建”,一种“放在哪个任务栈”。

在Manifest中,LaunchMode属性控制Activity“是否重新创建”,TaskAffinity属性则是控制“任务栈”的,这两个属性可以同时生效。

在代码中,启动Activity时,通过intent.addFlag()来添加各种Flag,每一种Flag都包含了Activity“是否重新创建”和“放在哪个任务栈”两个属性,还包含一些其它特性,后面会提到。通过该方法设置模式会覆盖manifest中的模式。

1、LaunchMode
standard:
标准模式,这是系统默认模式。每次启动Activity都会创建一个新的实例。

singleTop:
栈顶复用模式。如果Activity已经位于栈顶,则不会调用onCreate方法重建,只会调用onNewIntent方法启动;如果Acitvity不在栈顶,则重新创建;

singleTask:
栈内复用模式。通过一些方法可以指定Activity所在的栈(比如taskAffinity属性、FLAG等),如果Activity已经存在于指定栈中,则不会重建,只会调用onNewIntent方法,并销毁该Activity上面的Activity,让其处于栈顶;如果不存在指定栈指定栈中不存在该Activity,则在指定栈中重新创建;

singleInstance:
单例模式。如果Activity不存在(任何栈中都没有),就为该Activity创建一个栈,并创建该Activity;如果已经存在,就调用onNewIntent方法;在这个Activity中启动其它Activity,其它Acitivity不会在该栈中(具体在哪个栈取决于设置),该Acitivty是独占一个栈的。

2、任务栈相关
关于任务栈,有下面几条规则:
① 默认情况下,所有Activity都处于默认任务栈中,任务栈名就是包名;

② 默认情况下,新Activity与启动它的Activity在同一个栈中。所以,即使设置了TaskAffinity属性,也不会生效;

③ 当LaunchMode为singleTask、singleInstance时,设置TaskAffinity属性,新Acitvity就会在TaskAffinity属性指定的任务栈中创建;

④ 当Manifest中设置了allowTaskReparenting属性为true时,该Activity允许“转移任务栈”。举个例子来说明“转移任务栈”,应用A启动应用B中的某个Activity,此时,该Activity是由应用A启动,所以该Activity在应用A的任务栈中。然后点击Home键,从Home页面点击应用B图标时,启动B应用,不会启动MainActiviy,而是创建任务栈,把已被应用A启动的Activity转移到该任务栈中;

⑤ 从源码可以看出,只有发生resetTask时,才会发生“转移任务栈”,从Home页点击应用图标时,intent都会添加FLAG_ACTIVITY_RESET_TASK_IF_NEEDED属性,会发生“转移任务栈”;

3、Flag
Flag会设置多种属性,Flag值有很多,下面介绍几种常用的Flag。

FLAG_ACTIVITY_NEW_TASK:
与Manifest中设置singleTask效果一样;

FLAG_ACTIVITY_SINGLE_TOP:
与Manifest中设置singleTop效果一样;

FLAG_ACTIVITY_CLEAR_TOP:
如果该Activity已经存在,则销毁该Activity上面的Activity,然后再按照Manifest中设置launchMode来启动该Activity;如果该Activity不存在,就按launchMode来启动;

FLAG_ACTIVITY_NO_HISTORY:
原Activity1通过该flag启动Activity2,Activity2不会加入到原有栈中,但是通过Activity2启动Activity3时,Activity3又会加入原有栈中。通过返回键回退时,会跳过Activity2

IntentFilter

在Manifest中,通过设置Activity的intentFilter属性,来规定该Activity隐式启动的规则,当某个Intent能够与intentFilter中的内容匹配时,该Activity就会被启动。

先看Manifest中的格式

<intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <action android:name="android.intent.action.MAIN2" />
        <category android:name="android.intent.category.LAUNCHER" />
        <category android:name="android.intent.category.LAUNCHER2" />
        <data android:mimeType = "xxx/yyy"
                android:scheme = ""
                android:host = ""
                android:port = ""
                android:path = "">
</intent-filter>

intentFilter有三个标签:action、category、data,可以有多个action、多个category,只能有一个data

1、action的匹配规则
如果intentFilter中定义了action,intent中必就须有action,intent中的action只需要与filter中的其中任意一个匹配,就算成功;
如果intentFilter中没有定义action,那么不会进行匹配(算匹配成功)。

2、category的匹配规则
不管intentFilter中有没有category,如果intent中添加了category属性,添加的所有category都必须能对应到intentFilter中的category,才算成功;
如果intent中没有category,也算匹配成功。

2、data的匹配规则
如果intentFilter中定义了data,intent中必就须有data,intent中的data只需要与filter中的其中任意一个匹配,就算成功。
如果intentFilter中没有定义data,那么不会进行匹配(算匹配成功)。

如果这三种情况都匹配成功(匹配成功标准见上面),就可启动这个Activity了

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值