Activity的生命周期和启动模式

本文内容基于《Android开发艺术探索》,有兴趣的同学可以买本书,值得一看。

1.生命周期的各个过程

  • onCreate: 表示Activity正在被创建,Activity生命周期的第一个方法,可以做一些初始化工作。
  • onStart: 表示Activity正在启动,这时Activity已经可见但没有出现在前台,用户无法交互,可以理解为Activity已经显示出来,但我们看不到。
  • onRestart: 表示Activity正在重启,Activity从不可见变为可见状态。
  • onResume: 表示Activity已经可见并且出现在前台,是Activity获得用户焦点,在与用户交互。
  • onPause: 表示Activity正在停止,紧接着onStop将被调用,不能做耗时操作,因为只有onPause执行完新的Activity的onResume才会执行。
  • onStop: 表示Activity即将停止,不能做耗时操作。
  • onDestroy: 表示Activity即将被销毁,Activity生命周期的最后一个方法,可以做一些回收工作。

ActivityA第一次启动:onCreate->onStart->onResume:

1)当按下home键时:onPause->onStop.
2)当新打开ActivityB时:onPause->(B:onCreate->onStart->onResume)->onStop.

返回ActivityA时:(B:onPause->)onRestart->onStart->onResume->(B:onStop->onDestroy).

3)当按下back键时:onPause->onStop->onDestroy.
4)锁屏时:onPause->onStop. 解锁时:onStart->onResume。
5)配置改变时(如旋转屏幕):onPause->onStop->onDestroy->onCreate->onStart->onResume.

此时锁屏(横屏状态下):onPause->onStop->onDestroy->onCreate->onStart->onResume-> onPause 然后解锁(横屏状态下):onResume->onPause->onStop->onDestroy->onCreate->onStart->onResume

2.onSaveInstanceState和onRestoreInstanceState触发的时机:

当某个Activity变得容易被系统销毁时,onSaveInstanceState就会被执行(用户主动销毁除外,比如按back键),例如:

  1. 当用户按下HOME键时。

  2. 长按HOME键,选择运行其他的程序时。

  3. 按下电源按键(关闭屏幕显示)时。

  4. 从activity A中启动一个新的activity时。

  5. 屏幕方向切换时,例如从竖屏切换到横屏时。

onSaveInstanceState方法和onRestoreInstanceState方法“不一定”是成对的被调用的,onRestoreInstanceState被调用的前提是,Activity确实被系统销毁了。

3.Activity优先级:

  • 前台Activity:正在和用户交互的Activity,优先级最高。

  • 可见但非前台Activity:比如Activity中弹出一个对话框,此时Activity可见但无法和用户交互

  • 后台Activity:已经被暂停的Activity,比如执行了onStop,优先级最低。

优先级越低越有可能被系统销毁,如果一个进程没有四大组件在执行,那么该进程很快就会被系统杀死,因此一些后台工作不适合脱离四大组件独自运行在后台(可运行在service中)。

4.Activity的启动模式:

  • standard:标准模式,也是系统默认模式,不管实例是否存在,每次启动都会重新创建一个新的实例。

  • singleTop:栈顶复用模式,如果Activity位于任务栈栈顶那么Activity不会被重新创建同时会回调它的onNewIntent方法,如果Activity存在任务栈中但不在栈顶则会重新创建实例。

  • singleTask:栈内复用模式,是一种单实例模式,多次启动Acitivity都不会重新创建,会回调onNewIntent方法,并且清除该Activity任务栈上面的所有Activity(clearTop效果)。当一个具有singleTask模式的Activity请求启动时,比如ActivityA,系统首先会寻找是否存在A所需要的任务栈,如果不存在先创建一个任务栈,然后创建实例A并放到任务栈中,如果任务栈存在,则判断栈中是否有实例A,如果存在则把A调到任务栈顶,并回调A的onNewIntent,A上面的所有Activity都被移除,如果不存在则创建实例A放入到任务栈中。

  • singleInstance:单实例模式,是singleTask的加强模式,此种模式下的Activity只能单独位于一个任务栈,系统会为它单独创建一个任务栈,后续的请求不会创建新的Activity。singInstance和singleTask主要区别在与系统范围内的“实例唯一”还是当前Activity栈“实例唯一”。

假设目前有两个任务栈,前台任务栈中有AB(B位于栈顶),后台任务栈中有CD(D位于栈顶,CD启动模式为singleTask)。如果现在请求启动D,那么整个后台任务栈都会被切换到前台,按返回键后退的顺序是ABCD:ABCD->ABC->AB->A;如果请求启动C,整个后台任务栈也会被切换至前台,因为C是singleTask模式所以它会把D顶出去,按返回键后退的顺序是ABC:ABC->AB->A。

指定启动模式有两种方法:1.使用xml属性android:launchMode 2.使用代码intent.addFlags()。第二种方式优先于第一种,当两种都存在时以第二种为准,第一种不能设定FLAG_ACTIVITY_CLEAR_TOP标识,第二种无法设置singleInstance模式。

5.TaskAffinity

 这个参数标识一个Activity所需要的任务栈名称,默认不指定情况下,所有Activity所需的任务栈为应用的包
名。TaskAffinity属性主要和singleTask启动模式或者allowTaskReparenting属性配对使用:
  • TaskAffinity和singleTask:待启动的Activity会运行在名字和TaskAffinity相同的任务栈中。
  • TaskAffinity和allowTaskReparenting:当一个应用A启动了应用B的某个Activity后,如果这个allowTaskReparenting为true,那么应用B启动后,此Activity会从A的任务栈中转移到应用B的任务栈中。

6.Intent常用FLAG

  • Intent.FLAG_ACTIVITY_NEW_TASK:效果和singleTask一样
  • FLAG_ACTIVITY_SINGLE_TOP:效果和singleTop一样
  • FLAG_ACTIVITY_CLEAR_TOP:当它启动时,同一个任务栈中所有位于它上面的Activity都会被移除栈,如果实例已存在调用onNewIntent方法,如果被启动的Activity模式为standard,那么连同它和它之上的activity都会被移除,并重新创建实例放入栈顶,singleTask默认就用该标识位效果。
  • FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS:具有这个标记的Activity不会出现在历史Activity列表中,当某些情况下我们不希望用户通过历史列表回到我们的Activity的时候这个标记比较有用,它等同于属设置android:excludeFromRecents="true"

7.IntentFilter的匹配规则

IntentFilter中过滤信息如果有action、category、data三种,只有同时匹配了action、category、data才
算完全匹配,只有完全匹配才能启动Activity,此外一个Activity可以有多个intent-filter,一个intent只
要能匹配任何一组即可成功启动Activity
  • action匹配规则:只要能和规律规则中任何一个匹配即可匹配成功
  • category匹配规则:Intent中如果有category那么所有的category都必须和过滤规则中的其中一个category相同,如果没有category的话那么就是默认的category,即android.intent.category.DEFAULT,所以为了Activity能够接收隐式调用,配置多个category的时候必须加上默认的category。
  • data匹配规则:Intent中必须含有data数据,并且data数据能够完全匹配过滤规则中的某一个data。

如何判断是否有Activity能够匹配我们的隐式Intent?
(1)PackageManager的resolveActivity方法或者Intent的resolveActivity方法:如果找不到就会返回null
(2)PackageManager的queryIntentActivities方法:它返回所有成功匹配的Activity信息针对Service和BroadcastReceiver等组件,PackageManager同样提供了类似的方法去获取成功匹配的组件信息,例如queryIntentServices、queryBroadcastReceivers等方法

你可能感兴趣的:(Activity的生命周期和启动模式)