Activity的生命周期

Android的开发中我们大部分都是和Activity打交道,而想很好的运用Activity首先必须要清楚Activity的生命周期。接下来我们就聊聊Activity的生命周期。

一、认识Activity

Activity的中文意思就是活动,代表手机屏幕的一屏,或是平板中的一个窗口,提供了和用户交互的可视化界面。Activity是用于处理UI相关业务的,比如加载界面、监听用户操作等事件。

二、Activity的状态

(一)、Running状态: 一个新的Activity启动入栈后,它在屏幕的最前端,处于栈的最顶端,此时它处于可见并可和用户交互的激活状态,Android试图尽最大可能保持它活动状态,杀死其它Activity来确保当前活动Activity有足够的资源可使用。当另外一个Activity被激活,这个将会被暂停。

(二)、Paused状态:当Activity处于此状态时,此时它依然与窗口管理器保持连接,系统继续维护其内部状态,它仍然可见,但它已经失去了焦点,故不可与用户交互。

(三)、Stopped状态: 当Activity 不可见时,Activity处于Stopped状态。当Activity处于此状态时,一定要保存当前数据和当前的UI状态,否则一旦Activity退出或关闭时,当前的数据和UI状态就丢失了

(四)、Killed状态:Activity被杀掉以后或者被启动以前,处于Killed状态。这是Activity已从Activity堆栈中移除,需要重新启动才可以显示和使用。

三、Activity的生命周期

(一)、先看下官方的基本生命周期图,可以从下图中了解Activity的大概生命周期:

2018040310090767.jpg

(二)、生命周期的方法的介绍:

1.Activity正常的生命周期方法:

(1)onCreate方法:该方法是在Activity被创建时回调,它是生命周期第一个调用的方法,我们在创建Activity时一般 都需要重写该方法,然后在该方法中做一些初始化的操作,如:创建view、绑定数据到view。

(2)onStart方法:start表示启动,这是Activity生命周期的第二个方法。此时Activity已经可见了,但是还没出现在前台,我们还看不到,无法与Activity交互。其实将Activity的初始化工作放在这也没有什么问题,放在onCreate中是由 于官方推荐的以及我们开发的习惯。

(3)onResume方法:当此方法回调时,则说明Activity已在前台可见,可与用户交互了(处于前面所说的Active/Running形态),onResume方法与onStart的相同点是两者都表示Activity可见,只不过onStart回调时Activity还 是后台无法与用户交互,而onResume则已显示在前台,可与用户交互。当然从流程图,我们也可以看出当Activity停止后(onPause方法和onStop方法被调用),重新回到前台时也会调用onResume方法,因此我们也可以在 onResume方法中初始化一些资源,比如重新初始化在onPause或者onStop方法中释放的资源。

(4)onPause方法:当Activity要跳到另一个Activity或应用正常退出时都会执行这个方法。此时Activity显示在前台并可 见,我们可以进行一些轻量级的存储数据和初始化的工作,不能太耗时,因为在跳转Activity时只有当一个Activity执 行完 了onPause方法后另一个Activity才会启动,而且android中指定如果onPause在500ms即0.5秒内没有执行完毕的 话 就会强制关闭Activity。从生命周期图中发现可以在这快速重启,但这种情况其实很罕见,比如用户切到下一个Activity的途中按back键快速得切回来。

(5)onStop方法:紧接着onPause方法调用,此时Activity已经不再显示在用户面前了,此时新的Activity可能已经执行到onStart方法或者onResume方法了,所以此时可做一些较为重量级回收操作比方说关于数据库的一些读写操作等。

(6)onRestart方法:表示Activity正在重新启动,当Activity由不可见变为可见状态时,该方法被回调。这种情况一 般是用户打开了一个新的Activity时,当前的Activity就会被暂停(onPause和onStop被执行了),接着又回到当前 Activity页面时,onRestart方法就会被回调。 这里一般不做什么操作。

(7)onDestroy方法:该方法表示Activity生命周期中的最后一个方法,表示Activity方法将会被销毁,此时我们可以做 一些回收操作和最终的资源释放。这里需要提到的一点是,即使一个Activity被销毁后app内部的static变量是不会被销毁的,因为static变量是全局的,activity销毁但是该app的进程并没有被杀死。所以说这一点尤为需要注意我们的static变量的使用,否则稍有不慎再次启动该activity的时候该static变量就会是一个dirty data!

2、异常生命周期的两个方法:

(1)onSaveInstanceState方法:是用来保存UI状态的,在Activity杀死之前,你可以使用它保存你所想保存的东西,当 targetSdkVersion小于3时onSaveInstanceState是在onPause方法中调用的,而大于3时是在onStop方法中调用的。

(2)onRestoreInstanceState方法:恢复界面的状态,是在onStart之后、onResume之前调用的。

(三)、了解了生命周期的方法,接下来我们来分析生命周期方法调用的顺序。

1.以下是验证方法调用顺序的实例代码:

public class MainActivity extends Activity {

public static final String TAG = "MainActivity";
Button bt;
/** * Activity创建时被调用 * @param savedInstanceState */ @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
Log.e(TAG, "onCreate is invoke!!!");
bt= (android.widget.Button) findViewById(R.id.bt);
bt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
android.content.Intent i = new android.content.Intent(MainActivity.this,SecondActivity.class);
startActivity(i);
}
});
}

/** * Activity从后台重新回到前台时被调用 */ @Override
protected void onRestart() {
super.onRestart();
Log.e(TAG, "onRestart is invoke!!!");
}

/***Activity创建或者从后台重新回到前台时被调用 */
@Override
protected void onStart() {
super.onStart();
Log.e(TAG, "onStart is invoke!!!");
}

/***Activity创建或者从被覆盖、后台重新回到前台时被调用 */
@Override
protected void onResume() {
super.onResume();
Log.e(TAG, "onResume is invoke!!!");
}

/*** Activity被覆盖到下面或者锁屏时被调用 */
@Override
protected void onPause() {
super.onPause();
Log.e(TAG, "onPause is invoke!!!");
}

/** *退出当前Activity或者跳转到新Activity时被调用 */
@Override
protected void onStop() {
super.onStop();
Log.e(TAG, "onStop is invoke!!!");
}

/** *退出当前Activity时被调用,调用之后Activity就结束了 */
@Override
protected void onDestroy() {
super.onDestroy();
Log.e(TAG, "onDestroy is invoke!!!");
}
}

2.下面我们分析各种情况下,生命周期方法执行顺序:

(1)我们先来分析Activity启动过程中所调用的生命周期方法,运行程序如下:

04-03 11:20:42.107 26915-26915/com.jiusi.equiview E/MainActivity: onCreate is invoke!!!
04-03 11:20:42.157 26915-26915/com.jiusi.equiview E/MainActivity: onStart is invoke!!!

onResume is invoke!!!

从Log中我们可以看出Activity启动后,先调用了onCreate方法,然后是onStart方法,最后是onResume方法,进入运行状 态,此时Activity已在前台显示。因此, Activity启动–>onCreate()–>onStart()–>onResume()依次被调用。

(2)当前Activity创建完成后,按Home键回到主屏。运行如下:

04-03 11:22:00.447 26915-26915/com.jiusi.equiview E/MainActivity: onPause is invoke!!!

04-03 11:22:01.257 26915-26915/com.jiusi.equiview E/MainActivity: onStop is invoke!!!

我们在Activity创建完成后,点击Home回调主界面时,可以发现此时onPause方法和onStop方法被执行,也就是点击Home键回到主界面(Activity不可见)–>onPause()–>onStop()依次被调用。

(3)当前Activity创建完成后,按Back键回到主屏。运行如下:

04-03 11:23:15.097 26915-26915/com.jiusi.equiview E/MainActivity: onPause is invoke!!!
04-03 11:23:15.707 26915-26915/com.jiusi.equiview E/MainActivity: onStop is invoke!!!

04-03 11:23:15.717 26915-26915/com.jiusi.equiview E/MainActivity: onDestroy is invoke!!!

我们在Activity创建完成后,点击back键返回时,相当于退出了当前Activity,Activity将被销毁,可以发现此时onPause方法、onStop方法、onDestroy方法被执行,也就是点击Back键返回时(Activity不可见)–>onPause()–>onStop()–>onDestroy()依次被调用。

(4)当我们在原有的Activity的基础上打开新的Activity时。运行如下:

04-03 11:26:00.767 29335-29335/com.jiusi.equiview E/MainActivity: onPause is invoke!!!
04-03 11:26:00.817 29335-29335/com.jiusi.equiview E/SecondActivity: onCreate is invoke!!!
04-03 11:26:00.827 29335-29335/com.jiusi.equiview E/SecondActivity: onStart is invoke!!!
onResume is invoke!!!

04-03 11:26:01.087 29335-29335/com.jiusi.equiview E/MainActivity: onStop is invoke!!!

我们可看到首先调用了原来的Activity的onPause方法,接着调用新的Activity的onCreate(),onStart(),onResume()方法,然后再调用原来Activity的onStop方法。也就是说 在原Activity的基础上开启新的Activity,原Activity生命周期执行方法顺序为–>onPause()–>onStop(),事实上跟点击home键是一样的。但是这里有点要注意的是如果新的Activity使用了透明主题,那么当前Activity不会回调onStop方法。同时我们发现新Activity(SecondActivity)生命周期方法是在原Activity的onPause方法执行完成后才可以被回调,这也就是前面我们为什么说在onPause方法不能操作耗时任务的原因了。

(5)当我们在新的Activity的基础上返回时。运行如下:

04-03 11:29:47.227 29335-29335/com.jiusi.equiview E/SecondActivity: onPause is invoke!!!
04-03 11:29:47.257 29335-29335/com.jiusi.equiview E/MainActivity: onRestart is invoke!!!
onStart is invoke!!!
onResume is invoke!!!
04-03 11:29:47.517 29335-29335/com.jiusi.equiview E/SecondActivity: onStop is invoke!!!

04-03 11:29:47.527 29335-29335/com.jiusi.equiview E/SecondActivity: onDestroy is invoke!!!

我们可以看到执行完当前Activity的onPause方法后,接着就依次执行前一个Activity的onRestart、onStart、onResume,此时前一个Activity已经显示在前台了,接着就调用了当前Activity的onStop、onDestroy方法,当前Activity就销毁了。

我们总结下方法的调用顺序,当Activity启动时,依次会调用onCreate,onStart,onResume,而当Activity退居后台时(不可见,点击Home或者被新的Activity完全覆盖),onPause和onStop会依次被调用。当Activity重新回到前台(从桌面回到原Activity或者被覆盖后又回到原Activity)时,onRestart,onStart,onResume会依次被调用。当Activity退出销毁时(点击back键),onPause,onStop,onDestroy会依次被调用,到此Activity的整个生命周期方法回调完成。

现在我们再回头看看之前的流程图,应该是相当清晰明了了吧。这就是Activity整个典型的生命周期过程。

3.生命周期异常方法:

Activity的 onSaveInstanceState 和 onRestoreInstanceState并不是生命周期方法,它们不同于 onCreate、onDestroy等生命周期方法,它们并不一定会被触发。当应用遇到意外情况(如:内存不足、用户直接按Home键)由系统销毁一个Activity时,onSaveInstanceState会被调用。但是当用户主动去销毁一个Activity时,例如在应用中按返回键,onSaveInstanceState就不会被调用。因为在这种情况下,用户的行为决定了不需要保存Activity的状态。通常onSaveInstanceState()只适合用于保存一些临时性的状态,而onPause适合用于数据的持久化保存。
在Activity被杀掉之前调用保存每个实例的状态,以保证该状态可以在onCreate(Bundle)或者onRestoreInstanceState(Bundle) (传入的Bundle参数是由onSaveInstanceState封装好的)中恢复。这个方法在一个Activity被杀死前调用,当该Activity在将来某个时刻回来时可以恢复其先前状态。

例如,如果ActivityB启用后位于ActivityA的前端,在某个时刻ActivityA因为系统回收资源的问题要被杀掉,A通过onSaveInstanceState将有机会保存其用户界面状态,使得将来用户返回到ActivityA时能通过onCreate(Bundle)或者onRestoreInstanceState(Bundle)恢复界面的状态。

以上就是Activity生命周期的相关方法的一些介绍,有不合理之处请多指教!

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

推荐阅读更多精彩内容

  • 启动与销毁Activity 不同于使用 main() 方法启动应用的其他编程范例,Android 系统会通过调用对...
    安卓Boy阅读 1,769评论 3 5
  • 启动与销毁Activity 不同于使用 main() 方法启动应用的其他编程范例,Android 系统会通过调用对...
    mouekz阅读 644评论 0 0
  • 您的应用中的Activity应该做到如下需求: 1.用户在使用应用时接听来电或切换到另一个应用,它不会崩溃。 2....
    正阳Android阅读 526评论 1 0
  • 1.正常情况下的生命周期 1.onCreate: 与onDestory配对,表示Activity被创建,这是生命...
    S_ZY阅读 689评论 0 6
  • 时间过得飞快一转眼一年时间就过去了,先小小的感叹下啊。回到正题,最近在投简历看看是否有更好的机会和平台,很高兴得到...
    Elder阅读 1,169评论 3 5