Activity生命周期

生命周期

image.png
image.png

不要在onCreate,onStart,onResume,onPause几个方法进行耗时操作,否则会造成页面切换卡顿。

广播的注册和解绑要成对出现,比如在OnCreate中注册,在onStop或者onDestory中解绑,在 onResume中注册,在onPause中解绑。

Activity的四种状态

Activity的生命周期中存在四种基本的状态:活动状态(Active/Runing),暂停状态(Paused),停止状态(Stopped),销毁状态(Killed)。

活动状态

一个新的Activity入栈后,当处于Activity栈顶时,此事它处于可见并且能与用户进行交互。

期间触发的生命周期:onCreate()-> onStart()-> onResume()

暂停状态

当Activity失去焦点,一个新的非全屏Activity或者透明的Activity被放置栈顶,此时处于暂停状态。一个处于暂定状态的Activity只有在系统极度匮乏的时候才会被回收掉。

在Activity之上显示dialog对话框或者PopupWindow该Activity并不会变成暂停状态。
当下拉通知栏时,Activity会走什么生命周期?以及弹出Dialog时会走什么生命周期?关于这两知识点,今天特意写了一下,发现啥都没走,也就说任何生命周期都不会走,也简单查了一下原因,下拉通知栏因为是系统窗口,所以不影响activity的生命周期,Dialog或者Toast源码中也能看windowmanager.addView(),也就说都是和系统管理者有关系,不会影响到本应用。

运行状态到暂停状态触发的生命周期:onResume() --> onPause()
从暂停状态恢复到运行状态触发的生命周期:onPause() -> onResume()

停止状态

一个Activity完全被另一个Activity完全覆盖或者,用户不可见或者退到后台,叫做停止状态。它仍保存着所有状态和成员信息,不能和用户交互,当系统内存需要的时候Stopped状态的Activity会被强制回收掉。

从暂停状态到停止状态经过的生命周期:onPause()-->onStop()
从停止状态到运行状态经过的生命周期:onStop() --> onRestart() --> onStart() --> onResume()。不会走onCreate()方法。

销毁状态

如果一个Activity再Paused或者Stopped状态,系统可以将Activity从内存中删除,删除的方式有两种:一种是要求Activity结束,一种直接结束掉它的进程。当有需要的时候就得重新创建Activity了。

触发的生命周期:onDestroy(),直接结束进程的话是不会走onDestroy()的。

完整的生命周期

Activity完整的生命周期 :

  • onCreate()
  • onStart()
  • onResume()
  • onPause()
  • onStop()
  • onDestory()

onCreate()

onCreate方法会在Activity第一次被创建时调用。我们应该在这个方法中完成Activity的初始化操作,比如说加载布局,初始化布局控件,绑定按钮事件等。

特点

不可见,不可交互,可初始化数据。

注意:

在onCreate()方法中直接执行finish()会直接调用onDestroy()方法,不会走其它的生命周期。Activity在调用过该方法之后才会调用onStart方法,顺序执行,所以不要在该方法中做一些耗时的工作,影响界面的启动速度。

onStart()

onStart()方法会在onCreate()方法之后调用,或者在onRestart()方法之后调用。

此时Activity已经可见了,但是还没出现在前台,我们还看不到,无法与Activity交互

有两个地方会调用此方法:

  • 创建的时候
  • 暂停状态到活动状态

适合开启在Activity活跃状态下才要执行的任务:开始计时,接口轮询,启动广播,开启后台任务等。该方法不适合大量的数据初始化,因为它会执行多次。

注意

注意: 整个Activity生命周期中可别执行多次,切记一定要正确的使用该声明周期。

onResume()

这个方法在活动准备好和用户进行交互的时候调用。 此时的活动一定位于返回栈的栈顶,并且处于运行状态。

这里建议开启动画,或者打开一些独享设备(照相机)等的操作

onPause()

当Activity是去焦点后会被调用,这个方法在系统准备去启动或者恢复另一个活动的时候调用。 我们通常会在这个方法中将一些及其消耗 CPU 的资源释放掉(比如显示地图或者大规模图形),以及保存一些关键数据(比如用户输入的数据等等),但这个方法的执行速度一定要快,不然会影响到新的栈顶活动的使用。

onStop()

当Activity完全不可见时调用。此时Activity处于停止状态,当页面被完全遮挡,按下Home建页面进入后台,Activity销毁等。

该方法适合停止一些消耗资源的操作:结束倒计时,接口数据轮训,取消注册的广播,关闭后台的服务等。

onDestroy()

在Activity的整个生命周期中只会执行一次,也就是Activity将要被销毁的时候,通常是调用了finish()方法或者系统内存不足强制销毁。在这里一般要进行持有资源的全部释放工作,将集合清空,引用置为null,销毁一些单例,取消网络请求,以及清空Handler数据等等,保证不会出现内存泄漏的情况。可以调用Activity.isFinish去判断该Activity是否已经销毁。不要尝试再该方法中去保存一些数据,这只是系统的警告,我们还是会再该方法里面去保存一些SP数据的…另外:在某些情况下,系统会简单地终止活动的宿主进程,而不调用其中的此方法(或任何其他方法),因此不应将其用于执行进程结束后要保留重要数据的操作。

常见的生命周期的问题

当前Activity启动另外一个Activity,启动之后关掉新Activity的时候两个生命周期的变化:

ActivityA 启动 Activity B :
当前A:onResume()-->A:onPause() --> B:onCreate() -->B: onStart() --> B:onResume() --> A:onStop()

注意

ActivityB的开启必须经过A的onPause方法,所有 onPause方法尽量不要做耗时操作,影响下一个界面的开启。

屏幕旋转:

当屏幕旋转的时候Activity会销毁创建,这一点一定要记得,如果Activity发生泄漏的话旋转次数多了就会导致内存占用越多最终导致OOM。

在没有其它配置的情况下,通过日志打印屏幕旋转会调用的方法。
//onPause()----onStop()-----onDestroy()-----onCreate() ---- onStart()---onResume()
完整
onPause -->onSaveInstanceState -->onStop -->onDestroy -->onCreate-->onStart -->onRestoreInstanceState-->onResume

按home键

Activity进入后台:
onResume() --> onPause() --> onStop()

回到前台:
onRestart() --> onStart() --> onResume()

物理返回键onKeyDown方法

Activity : onPause() -> onStop() -> onDestroy()。

系统回收

首先每个应用最少有一个进程,我们的Activity都是运行在进程中的,当应用退到后台时,系统可能因为内存不足而杀掉优先级低的进程,那么再该进程中的Activity都会被杀死,这种情况是不会走Activity的生命周期的,只有杀掉单个Activity的时候才会走Activity的onDestroy()方法。

调用finish方法

调用finish()方法的时候需要区分在那个生命周期内执行的该方法,这里是执行并不是在那个生命周期内写了finishi()的代码。

onCreate()生命周期内直接执行了finish()方法: onCreate() -> onDestroy()。

onStart()生命周期内直接执行了finish()方法: onCreate() -> onStart() -> onStop() -> onDestroy()。

onResume()生命周期内直接执行了finish()方法:onCreate() -> onStart() -> onResume() -> onPause() -> onStop() -> onDestroy()。

Dialog,PopupWindow或者DialogActivity:

当Activity之上显示出Dialog或者PopupWindow的时候是不会走任何的生命周期的,Toast也是一样的。当出现了Dialog风格的Activity的时候会走 onPause() -> onSaveInstanceState()。消失后会走onResume()。

息屏时再打开

  • 息屏
    onPause() --> onStop()

  • 在打开

'onRestart() --> onStart() --> onResume()'

启动一个再前台的且启动模式为singleTop的Activity

Activity : onPause() -> onNewIntent() -> onResume()。

再当前Activity界面进入设置界面更改了一些已有的设置,或者Activity发生异常奔溃重建:

Activity : onPause() -> onStop() -> onDestroy() -> onCreate() -> onStart() (会执行这个方法onRestoreInstance() )-> onResume()。

假设项目中有这样的需求,当指定的 Activity 在用户可见后才进行广播的注册,在用户不可见后对广播进行注销,那应该在哪两个回调中做这个处理呢?

问题中强调了「可见」和「不可见」,所以我们只需要注重可见生命周期,在Activity 启动后,会先调用 onCreat() 方法进行布局和想关事件的绑定,直到回调 onStart() 方法后活动才可见,所以直接回答 onStart() 和 onStop() 即可。

如果有一些数据在 Activity 跳转时(或者离开时)要保存到数据库,那么你认为是在 onPause() 好还是在 onStop() 执行这个操作好呢?

onPause() 相比 onStop() 更容易触发。而「数据」就是 APP 甚至互联网产品的根,我们虽然绝大多数情况下都会遵从 onPause() => onStop() 的原则,但我们实在难以保证每次运行都能正常运行到 onStop() 方法,比如还没运行到 onStop() 系统就被回收了。

值得注意的是,这个操作要尽量地快,不然肯定会影响到下一个 Activity 的生命周期的。

什么时候Activity单独走onPause()不走onStop()?

start一个设置为android:theme="@android:style/Theme.Dialog"的Activity,当前Activity才会只走onPause()。

什么时候Activity不执行onDestroy()

进程重要等级和Activity的关系

前台>可见>服务>后台>空

  • 前台:与当前用户正在交互的Activity所在的进程。

  • 可见:Activity可见但是没有在前台所在的进程。

  • 服务:Activity在后台开启了Service服务所在的进程。

  • 后台:Activity完全处于后台所在的进程。

  • 空:没有任何Activity存在的进程,优先级也是最低的。

onSaveInstanceState()被执行的场景有哪些:

  • 当用户按下HOME键时
  • 长按HOME键,选择运行其他的程序时
  • 锁屏时
  • 从activity A中启动一个新的activity时
  • 屏幕方向切换时

下拉状态栏时Activity的生命周期

下拉状态栏对生命周期没有任何影响,弹出AlertDialog、Toast时都没有影响,重新理解下onPause(),应该修正为“被Activity遮挡”

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

推荐阅读更多精彩内容