目录
Activity的生命周期全面分析
典型情况下的生命周期分析
异常情况下的生命周期分析
情况1:资源相关的系统配置发生改变导致Activity被杀死并重新创建
Activity的生命周期全面分析
在Android开发中,Activity的生命周期是非常重要的概念。它描述了Activity在不同状态下的转换过程。根据你提供的内容,Activity的生命周期可以分为两部分:
-
典型情况下的生命周期:这是指在有用户参与的情况下,Activity所经历的生命周期变化。这些状态包括:
-
onCreate(Bundle savedInstanceState)
:Activity创建时调用。 -
onStart()
:Activity变为可见时调用。 -
onResume()
:Activity开始与用户交互时调用。 -
onPause()
:Activity失去焦点,但不一定会停止时调用。 -
onStop()
:Activity不可见时调用。 -
onDestroy()
:Activity销毁时调用。
-
-
异常情况下的生命周期:这是指Activity由于系统回收或者设备配置发生变化(如屏幕旋转)导致Activity被销毁重建时的生命周期。在这种情况下,关注点和典型情况下略有不同,主要关注:
-
onSaveInstanceState(Bundle outState)
:在Activity因配置更改或内存不足被销毁前调用,用于保存状态。 -
onRestoreInstanceState(Bundle savedInstanceState)
:在Activity重建时调用,用于恢复之前保存的状态。
-
这些生命周期方法允许开发者管理Activity的状态,确保在Activity重建时用户界面和数据能够正确恢复。
典型情况下的生命周期分析
在正常情况下,Activity会经历如下生命周期:
-
onCreate():
-
作用:Activity正在被创建,这是生命周期的第一个方法。
-
使用场景:比如调用setContentViView去加载界面布局资源、初始化Activity所需数据等。
-
-
onRestart():
-
作用:Activity正在重新启动,从不可见面重新变为可见状态时调用。
-
使用场景:这种情形一般是用户行为所导致的,比如用户按Home键切换到桌面或者用户打开了一个新的Activity,这时当前的Activity就会暂停,也就是onPause和onStop被执行了,接着用户又回到了这个Activity,就会出现这种情况。
-
-
onStart():
-
作用:Activity正在被启动,即将开始,此时Activity已经可见,但还没有出现在前台,无法和用户交互。
-
使用场景:可以理解为Activity已经显示出来了,但用户还看不到。
-
-
onResume():
-
作用:Activity已经可见,并且出现在前台并开始活动。
-
使用场景:要注意这个和onStart的对比,onStart和onResume都表示Activity已经可见,但是onStart的时候Activity还在后台,onResume的时候Activity才显示到前台。
-
-
onPause():
-
作用:Activity正在停止,正常情况下,紧接着onStop就会被调用。
-
使用场景:用户切换到另一个Activity或按下Home键,或者有新的Activity覆盖了当前Activity。
-
在特殊情况下,如果这个时候快速地再回到当前Activity,那么onResume会被调用。笔者的理解是,这种情况属于极端情况,用户操作很难重现这一场景。此时可以做一些存储数据、停止动画等工作,但是注意不能太耗时,因为这会影响到新Activity的显示,onPause必须先执行完,新Activity的onResume才会执行。
-
-
onStop():
-
作用:Activity即将停止,可以做一些稍微重量级的回收工作。
-
使用场景:Activity不再可见,如被新的Activity覆盖,或者用户切换到了其他应用。
-
-
onDestroy():
-
作用:Activity即将被销毁,这是Activity生命周期中的最后一个回调。
-
使用场景:Activity的整个生命周期结束,进行资源释放和回收工作。
-
Activity的生命周期回调顺序对于理解Activity的行为至关重要。以下是一些典型的生命周期回调场景:
-
第一次启动Activity:
-
回调顺序:onCreate -> onStart -> onResume。
-
描述:Activity从创建到显示在用户面前的过程。
-
-
用户打开新的Activity或切换到桌面:
-
回调顺序:onPause -> onStop。
-
描述:当前Activity失去焦点,变为不可见状态。
-
特殊情况:如果新Activity采用了透明主题,当前Activity可能不会回调onStop。
-
-
用户再次回到原Activity:
-
回调顺序:onRestart -> onStart -> onResume。
-
描述:Activity从后台重新回到前台。
-
-
用户按back键回退:
-
回调顺序:onPause -> onStop -> onDestroy。
-
描述:Activity从前台消失,被销毁。
-
-
Activity被系统回收后再次打开:
-
回调顺序:与第一次启动相同,即onCreate -> onStart -> onResume。
-
注意:虽然生命周期方法回调相同,但不代表所有过程都一样。
-
-
Activity的整个生命周期:
-
onCreate和onDestroy是配对的,分别标识Activity的创建和销毁。并且只可能有一次调用。
-
onStart和onStop是配对的,表示Activity是否可见。
-
onResume和onPause是配对的,表示Activity是否位于前台。随着用户的操作或者设备屏幕的点亮和熄灭,这四个方法可能被调用多次
-
小问题:
-
onStart和onResume、onPause和onStop从描述上来看差不多,对我们来说有什么实质的不同呢?
先说第一个问题,从实际使用过程来说,onStart和onResume、onPause和onStop看起来的确差不多,甚至我们可以只保留其中一对,比如只保留onStart和onStop。既然如此,那为什么Android系统还要提供看起来重复的接口呢?根据上面的分析,我们知道,这两个配对的回调分别表示不同的意义,onStart和onStop是从Activity是否可见这个角度来回调的,而onResume和onPause是从Activity是否位于前台这个角度来回调的,除了这种区别,在实际使用中没有其他明显区别。
-
假设当前Activity为A,如果这时用户打开一个新ActivityB,那么B的onResume和A的onPause哪个先执行呢?
在新Activity启动之前,桟顶的Activity需要先onPause后,新Activity才能启动。
旧Activity的onPause先调用,然后新Activity才启动,这也证实了我们上面的分析过程。也许有人会问,你只是分析了Android5.0的源码,你怎么知道所有版本的源码都是相同逻辑呢?关于这个问题,我们的确不大可能把所有版本的源码都分析一遍,但是作为Android运行过程的基本机制,随着版本的更新并不会有大的调整,因为Android系统也需要兼容性,不能说在不同版本上同一个运行机制有着截然不同的表现。关于这一点我们需要把握一个度,就是对于Android运行的基本机制在不同Android版本上具有延续性。
从另一个角度来说,Android官方文档对onPause的解释有这么一句:不能在onPause中做重量级的操作,因为必须onPause执行完成以后新Activity才能Resume,从这一点也能间接证明我们的结论。
通过分析这个问题,我们知道onPause和onStop都不能执行耗时的操作,尤其是onPause,这也意味着,我们应当尽量在onStop中做操作,从而使得新Activity尽快显示出来并切换到前台。
异常情况下的生命周期分析
Activity除了受用户操作所导致的正常的生命周期方法调度,还有一些异常情况,比如当资源相关的系统配置发生改变以及系统内存不足时,Activity就可能被杀死
资源相关的系统配置发生改变导致Activity被杀死并重新创建
理解这个问题,我们首先要对系统的资源加载机制有一定了解,这里不详细分析系统的资源加载机制,只是简单说明一下。拿最简单的图片来说,当我们把一张图片放在drawable目录后,就可以通过Resources去获取这张图片。同时为了兼容不同的设备,我们可能还需要在其他一些目录放置不同的图片,比如drawable-mdpi、drawablehdpi、drawable-land等。这样,当应用程序启动时,系统就会根据当前设备的情况去加载合适的Resources资源,比如说横屏手机和竖屏手机会拿到两张不同的图片(设定了landscape或者portrait状态下的图片)。比如说当前Activity处于竖屏状态,如果突然旋转屏幕,由于系统配置发生了改变,在默认情况下,Activity就会被销毁并且重新创建,当然我们也可以阻止系统重新创建我们的Activity。在默认情况下,如果我们的Activity不做特殊处理,那么当系统配置发生改变后,Activity就会被销毁并重新创建
当系统配置发生改变后,Activity会被销毁,其onPause、onStop、onDestroy均会被调用,同时由于Activity是在异常情况下终止的,系统会调用onSaveInstanceState来保存当前Activity的状态。这个方法的调用时机是在onStop之前,它和onPause没有既定的时序关系,它既可能在onPause之前调用,也可能在onPause之后调用。需要强调的一点是,这个方法只会出现在Activity被异常终止的情况下,正常情况下系统 不 会 回 调 这 个 方 法 。 当 Activity 被 重 新 创 建 后 , 系 统 会 调 用onRestoreInstanceState,并且把Activity销毁时onSaveInstanceState方法所保存的Bundle对象作为参数同时传递给onRestoreInstanceState和onCreate方法。因此,我们可以通过onRestoreInstanceState和onCreate方法来判断Activity是否被重建了,如果被重建了,那么我们就可以取出之前保存的数据并恢复,从时序上来说,onRestoreInstanceState的调用时机在onStart之后。