Activity的生命周期与启动模式总结

一、Activity的生命周期:

1、典型情况下Activity的生命周期(详见Activity的生命周期的图):
  • ①onCreate:与onDestory相对应,表示Activity正在被创建,这是生命周期的第一个方法,主要做一些初始化的工作,比如用setContentView去加载布局资源,初始化Activity等。耗时的工作在异步线程上完成

  • ②onStart:与onStop相对应,表示Activity即将开始,这时的Activity已经可见,但是还没有出现在前台,还无法与用户交互。

  • ③onResume:表示Activity已经可以看见了,并且出现在前台,可以与用户产生交互了。

  • ④onPause:与onResume相对应,表示Activity正在暂停,正常情况下,onStop接着就会被调用。在特殊情况下,如果这个时候用户快速地再回到当前的Activity,那么onResume会被调用(极端情况)。一般来说,在这个生命周期状态下,可以做一些存储数据、停止动画的工作,但是不能太耗时,如果是由于启动新的Activity而唤醒的该状态,那会影响到新Activity的显示,原因是onPause必须执行完,新的Activity的onResume才会执行。(Activity此时是可见的:dialog,或者新Activity的主题是透明的)

  • ⑤onStop:表示Activity即将停止,已经不可见,同样不能做过多耗时操作。

  • ⑥onDestroy:表示Activity即将被销毁,这是Activity的最后一个生命周期,可以做一些回收工作和最终的资源释放。

  • ⑦onRestart:表示Activity正在重新启动。一般情况下,在当前Activity从不可见重新变为可见的状态时onRestart就会被调用。这种情形一般是由于用户的行为所导致的,比如用户按下Home键切换到桌面或者打开了一个新的Activity(这时当前Activity会暂停,也就是onPause和onStop被执行),接着用户有回到了这个Activity,就会出现这种情况。

  • 生命周期图:

image-20200201165900840.png
2、注意几点:

①当用户按下Back键回退时,回调onPause,onStop,onDestroy

②HOME键的执行顺序:onPause->onStop->onRestart->onStart->onResume BACK键的顺序: onPause->onStop->onDestroy->(新的Activity)onCreate->onStart->onResume

③在ActivityA启动ActivityB的时候,需要activityA先执行onPause,ActivityB才会创建(onCreate,onStart,onResume)。

④finish的具体操作:

  • 只是将活动推向后台,将Activity移出栈,并没有及时的调用onDestory()方法,其占用的资源也没有被及时释放

  • 在Activity中的onCreate中调用finish,则执行到的声明周期方法有:onCreate,onDestroy

  • 在Activity的onStart()中调用finish()方法,则执行的生命周期方法顺序为: onCreate() -> onStart() -> onStop() -> onDestroy()

  • 在Activity的onResume()或onPostResume()中调用finish()方法,则执行的生命周期方法顺序为: onCreate() -> onStart() -> onResume() -> onPause() -> onStop() -> onDestroy()

⑤Activity的启动过程:简单的说就是请求Activity的请求是交给Instrumentation来处理,然后通过Binder向AMS发送请求,AMS内部维护一个ActivityStack并负责Activity的状态同步,AMS通过ActivityThread去同步Activity的状态而完成生命周期方法的调用(有待扩充)。

3、异常情况下Activity的生命周期(Activity被系统回收或者由于当前设备的configuration发生改变从而导致Activity被销毁重建):
  • 资源相关的系统配置发生改变时,Activity被杀死并重新创建(比如:Activity处于竖直状态,如果突然旋转屏幕,由于系统配置发生了改变,在默认情况下,Activity就会被销毁并且重新创建,当然可以阻止系统重新创建新的Activity(android:configChanges="orientation|screenSize"),加上screenSize是因为minSdkVersion和targetSdkVersion有一个大于了13。

  • Activity在异常情况下被终止,系统会调用onSaveinstanceState来保存当前Activity的状态,并且调用时机是在onStop之前,与onPause没有特定的时序关系。正常情况下,不会调用这个方法。当新Activity被重新创建的时候,系统会调用onRestoreInstanceState来回复数据,在onstart之后执行onRestoreInstanceState。

  • 资源内存不足导致低优先级的Activity被杀死:当系统内存不足时,系统就会按照上述优先级去杀死目标Activity所在的进程,并后续通过onSaveInstanceState和onRestoreInstanceState来存储和回复数据。

  • 当Activity在异常情况销毁的时候,系统会默认保存当前Activity的视图结构,并且在Activity重启的时候为我们恢复这些数据(文本框的输入数据,ListView的滚动位置等)。保存和恢复View的层次结构,系统的工作流程如下:当Activity会调用onSaveInstanceState去保存数据,然后委托Window去保存数据,接着Window再委托它的上级容器去保存数据,顶级是一个Viewgroup,很可能是一个DecorView,然后顶级容器再去一一通知它的子元素去保存数据。

二、Activity的启动模式(4种)

1、standard:标准模式
  • 每次启动一个Activity都会重新创建一个新的实例,不管这个实例是否已经存在。并且谁启动了这个Activity,那么这个Activity就运行在启动它的这个Activity所在的栈中。
  • 运用非Activity的context去启动一个Activity时会出现AndroidRuntimeException异常,主要原因是ApplicationContext没有所谓的Activity任务栈,解决办法是为待启动的Activity指定:FLAG_ACTIVITY_NEW_TASK的标记位,此时相当于singleTask的启动模式
2、singleTop:栈顶复用模式
  • 如果新的Activity已经位于任务栈的栈顶,那么此Activity不会被重新创建,同时它的onNewIntent方法会被调用,同时该Activity的onCreate和onStart则不会被调用。(注意需要从onNewIntent的intent中获取新的值,否则用的还是原来intent中的值)
  • 如果新的Activity已经位于任务栈但不是位于栈顶,或者栈中不存在,则这个Activity会被重新创建(oncreate,onStart,onResume)。
3、singleTask:栈内复用模式(单实例模式)
  • 当一个具有singleTask模式的Activity A 请求启动,系统首先会寻找是否存在A想要的任务栈(TaskAffinity指定任务栈的名称),如果不存在,就先创建一个A的任务栈,并将A的实例放入栈中。
  • 如果存在A需要的任务栈,则首先判断是否存在A的实例,如果存在,则调用A的onNewIntent,并将处于A上面的Activity出栈(singleTask自带clearTop,但是使用标志位启动时需要使用:FLAG_ACTIVITY_NEW_TASK和FLAG_ACTIVITY_CLEAR_TOP标志位),使得A处于栈顶的位置。 如果不存在,则创建一个A的实例,放置于该栈的栈顶。
4、singleInstance:单实例模式
  • 具有此模式的Activity只能单独的位于一个任务栈中。
  • 比如Activity A 是singleInstance模式,当A启动后,系统会为它创建一个新的任务栈。A独自运行在这个任务栈中,后续的请求均不会创建新的Activity,除非这个独特的任务栈被系统销毁了。

三、TaskAffinity:主要和singleTask启动模式或者allowTaskReparenting属性配对使用,其他情况下没有意义。

  • ①当TaskAffinity和singleTask启动模式配对的时候,它是具有该模式Activity的目前任务栈的名字,待启动的Activity会运行在名字和TaskAffinity相同的任务栈中,Activity默认的任务栈的名称为包名。
  • ②当TaskAffinity和allowTaskReparenting配对的时候,当应用A启动应用B的Activity C后,当按下home键,再启动应用B时,如果Activity的allowTaskReparenting属性为true,C会从A的任务栈转移到B的任务栈中。

四、如何给Activity指定启动模式:

  • ①在AndroidManifest中指定launchMode.(无法为Activity设置FLAG_ACTIVITY_CLEAR_TOP标识)
  • ②通过Intent(优先级更高,但是无法指定singleInstance模式):
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)

五、Activity常用的Flags

  • ①FLAG_ACTIVITY_NEW_TASK:作用是为Activity指定"singleTask"的启动模式
  • ②FLAG_ACTIVITY_SINGLE_TOP:作用是为Activity指定"singleTop"的启动模式
  • ③FLAG_ACTIVITY_CLEAR_TOP:具有此标志位的Activity,当它启动时,在同一个任务栈中所有位于它上面的Activity都要出栈,这个标志位一般会和singleTask启动模式一起出现。
  • ④FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS:具有这个标志位的Activity不会出现在历史Activity的列表中,当某些情况,我们不需要通过历史列表回到我们的Activity的时候,这个标记比较有用。其等同于:android:excludeFromRecents = "true".

六、显示Intent和隐式Intent:

  • ①显示Intent:(指明了要跳到哪个Activity或者Service,包括包名和类名)
    Intent intent = new Intent(Activity1.this,Activity2.class)
  • ②隐式Intent:(没有指明要跳转的类)在AndroidManifest中的intent-filter中实现过滤。intentFilter的过滤信息有action,category,data.一个Activity可以有多个intent-filter,一个Intent只要能匹配任何一组intent-filter即可成功启动对应的Activity.
  • ③action的匹配规则:要求Intent的action存在且必须和过滤规则中的其中一个action相同,action区分大小写,大小写不同字符串相同的action会匹配失效。
  • ④category的匹配规则:category的匹配规则和action不一样,要求Intent中如果含有category,那么所有的category都必须和过滤规则中的某个category相同。(Intent可以不设置category,但是Intent必须设置action)
  • ⑤data的匹配规则:与action类似,如果Intent中定义了data,那么Intent中必须定义可匹配的data.
    data由两部分组成,mimeType(媒体类型)和URI(http://www.baidu.com:80/search/info)<shcheme>://<host>:<port>/[<path>|<pathPrefix>|<pathPattern>]。
  • ⑥在隐式Intent跳转的时候,最好做一下IntentFilter的判断。看是否有Activity可以匹配的IntentFilter.
    • a、采用PackageManager的resolveActivity方法或者Intent的resolveActivity,如果找不到可以匹配的Activity,就返回空。
    • b、PackageManager还提供了queryIntentActivities方法,不是返回最佳匹配的Activity信息,而是返回所有成功匹配的Activity的Activity信息。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342