Activity生命周期详细解读(含部分源码)

前言

对于Activity的生命周期大家都很熟悉,有onCreate、onStart、onResume、onPause、onStop、onDestroy这几个方法。

本文将讲述关于Activity生命周期更深层次的知识(部分内容从源码角度解读),并且讲述一下不常被提及,却十分重要的概念。

生命周期概述

Activity生命周期

几种生命周期

(1)onCreate:表是Activity正在创建,是生命周期的第一个方法,主要进行加载布局、初始化Window等操作。

(2)onRestart:表示Activity正在重新启动,当Activity由不可见变为可见时调用。这一行为主要是由用户触发(Back或切换应用等操作)。

(3)onStart:表示Activity正在启动,这时Activity已经可见了,只是还没有出现在前台,无法和用户交互。

(4)onResume:表示Activity已经可见了,这时Activity已经可见了,并且出现在了前台,可以和用户进行交互。onStart和onResume都表示Activity已经可见了,但是onResume时,Activity才会显示到前台,并且可以进行交互。

(5)onPause:表示Activity正在暂停,后面通常会调用onStop方法(部分特例请看下文)。onPause可以做一些数据暂存、动画关闭等操作,不能进行耗时操作,因为下一个Activity启动前,必须要当前Activity已经Pause后才能显示(具体原因请看下文),耗时操作会影响到下一个页面的显示。

(6)onStop:表示Activity正在停止,可以进行一些略重量级的回收工作,但也不能太耗时。

(7)onDestroy:表示Activity正在被销毁,是Activity生命周期的最后一个回调,可以进行最终的资源释放(unRegister或unBind)。

常规生命周期切换

(1)新建一个Activity,新Activity的生命周期回调如下:onCreate->onStart->onResume。
(2)新建一个Activity,原Activity的生命周期回调如下:onPause->onStop(部分情况下不调用)。这里需要需要注意,当新页面使用透明、Dialog主题时,原页面并不会调用onPause方法。
(3)当用户Back时,原Activity的生命周期回调如下:onRestart->onStart->onResume。
(4)当用户Back时,当前Activity的生命周期回调如下:onPause->onStop->onDestroy。
(5)Activity被回收后重新打开时,生命周期回调同(1),但是系统会自动进行一些数据、状态的保存和恢复工作。

何时生命周期不回调onStop方法?

当原页面未被完全覆盖时,即启动的页面为Dialog或透明主题,原页面不会回调onStop方法。

设置Dialog主题

Activity

<activity
    android:name=".Main2Activity"
    android:theme="@android:style/Theme.Dialog"/>

AppCompatActivity

<activity
    android:name=".Main2Activity"
    android:theme="@style/Theme.AppCompat.Dialog"/>

设置透明主题

Activity

<activity
    android:name=".Main2Activity"
    android:theme="@android:style/Theme.Translucent" />

AppCompatActivity

<style name="MyTranslucentTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowBackground">#00000000</item>
    <item name="android:windowIsTranslucent">true</item>
</style>
<activity
    android:name=".Main2Activity"
    android:theme="@style/MyTranslucentTheme" />

实例验证

依据以上方法设置ActivityB主题,验证log如下:

2019-05-12 00:30:59.526 4740-4740/com.gcc.demo D/ActivityA: onCreate:
2019-05-12 00:30:59.527 4740-4740/com.gcc.demo D/ActivityA: onStart:
2019-05-12 00:30:59.529 4740-4740/com.gcc.demo D/ActivityA: onResume:
2019-05-12 00:31:01.706 4740-4740/com.gcc.demo D/ActivityA: onClick: +++++++++++++++++++启动ActivityB
2019-05-12 00:31:01.718 4740-4740/com.gcc.demo D/ActivityA: onPause:
2019-05-12 00:31:01.760 4740-4740/com.gcc.demo D/ActivityB: onCreate:
2019-05-12 00:31:01.761 4740-4740/com.gcc.demo D/ActivityB: onStart:
2019-05-12 00:31:01.766 4740-4740/com.gcc.demo D/ActivityB: onResume:

新页面的onResume和原页面的onPause谁先调用?

前文说到新页面调用onResume前,原页面的onPause必须先调用,具体原因我们从源码中获取。下面贴一段Android9.0中ActivityStack类的resumeTopActivityInnerLocked方法的源码:


Android9.0-ActivityStack-resumeTopActivityInnerLocked方法

If the flag RESUME_WHILE_PAUSING is set, then continue to schedule the previous activity to be paused, while at the same time resuming the new resume activity only if the previous activity can't go into Pip since we want to give Pip activities a chance toenter Pip before resuming the next activity.

从上面这段源码以及相应注释可以看出,如果没有设置RESUME_WHILE_PAUSING这个Flag,那么新页面调用onResume时,原页面的onPause必须先调用

系统配置发生改变时Activity被重新创建

Activity重建时的生命周期

当系统的配置发生改变时(例如手机横竖屏切换、系统语言切换等),Activity会被重新创建。此时Activity生命周期和创建时一样,只不过这时候Activity会调用onSaveInstanceStateonRestoreInstanceState这一组方法来进行页面数据的缓存以及恢复(正常启动Activity时不会触发该组方法)。

PS:Activity的数据缓存与恢复可以看本人另一篇文章
Android如何应对内存回收机制

如何避免配置修改后Activity被重建

如果不想系统配置修改后重启Activity,也可以给configChanges添加不需要重启的指定配置项。例如,横竖屏、语言变化时不想重启Activity,可这样写:

<activity
    android:name=".Main2Activity"
    android:configChanges="locale|orientation" />

PS:configChanges详细配置请看本人另一篇文章
Android修改系统设置后Activity被重新创建

Activity被系统回收后再次重建

当系统内存不足时,Android系统会自动回收一些低优先级的进程,或者回收一些已被停止的后台Activity。

Activity优先级

Activity优先级如下,由高到低:

  1. 前台Activity--正在和用户交互的Activity。高优先级。
  2. 可见但不可交互Activity--上层页面为Dialog、透明主题,即已Pause但未Stop的页面。中优先级。
  3. 后台Activity--已Stop的Activity。低优先级。

Activity重建时的生命周期

Activity被重建时,Activity生命周期和新建时一样,只不过这时候Activity也会调用onSaveInstanceStateonRestoreInstanceState这一组方法来进行页面数据的缓存以及恢复(正常启动Activity时不会触发该组方法)。

PS:如何处理内存被回收可以看本人另一篇文章
Android如何应对内存回收机制

NewIntent状态下的生命周期

什么情况下会触发onNewIntent回调方法?

这个问题我们从源码中求解。下面贴一段Android9.0中Activity类的startActivityIfNeeded方法的头注释:

Android9.0-Activity-startActivityIfNeeded注释

if you are using the {@link Intent#FLAG_ACTIVITY_SINGLE_TOP} flag, or singleTask or singleTop and the activity that handles <var>intent</var> is the same as your currently running activity , then a new instance is not needed.

从注释中可以看出,在不需要创建一个新的Activity实例时,生命周期会回调onNewIntent方法。不需要创建新Activity实例主要有这两种情况:
(1)启动模式为singleTask,且栈内已存在待创建实例;
(2)启动模式为singleTop,且栈顶就是待创建实例。

触发onNewIntent方法时,Activity生命周期是怎样的?

在singleTask和singleTop启动模式下,启动一个已存在的Activity(PS:只看在栈顶的情况),该Activity的生命周期会如何回调呢?

回调的时序应该是onPause->onNewIntent->onResume。

触发onNewIntent回调的注意事项

在回调onNewIntent方法时,需要注意将onNewIntent传入的intent替换为当前Intent,否则新Intent附加值并不会被传递给页面。需要调用如下方法:

setIntent方法
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容