首页 > 程序开发 > 移动开发 > Android >

Android总结篇系列:Activity生命周期

2017-04-24

Android总结篇系列:Activity生命周期,Android官方文档和其他不少资料都对Activity生命周期进行了详细介绍,在结合资料和项目开发过程中遇到的问题,本文将对Activity生命周期进行一次总结。

Android总结篇系列:Activity生命周期,Android官方文档和其他不少资料都对Activity生命周期进行了详细介绍,在结合资料和项目开发过程中遇到的问题,本文将对Activity生命周期进行一次总结。

Activity是由Activity栈进管理,当来到一个新的Activity后,此Activity将被加入到Activity栈顶,之前的Activity位于此Activity底部。Acitivity一般意义上有四种状态:

1.当Activity位于栈顶时,此时正好处于屏幕最前方,此时处于运行状态

2.当Activity失去了焦点但仍然对用于可见(如栈顶的Activity是透明的或者栈顶Activity并不是铺满整个手机屏幕),此时处于暂停状态

3.当Activity被其他Activity完全遮挡,此时此Activity对用户不可见,此时处于停止状态

4.当Activity由于人为或系统原因(如低内存等)被销毁,此时处于销毁状态

在每个不同的状态阶段,Adnroid系统对Activity内相应的方法进行了回调。因此,我们在程序中写Activity时,一般都是继承Activity类并重写相应的回调方法。

先贴一张来自官方文档的图,相信大家都看到过。这里写图片描述

图中详细给出了Activity整个生命周期的过程,以及在不同的状态期间相应的回调方法。

图中需要注意一下几点:

1.Activity实例是由系统自动创建,并在不同的状态期间回调相应的方法。一个最简单的完整的Activity生命周期会按照如下顺序回调:onCreate -> onStart -> onResume -> onPause -> onStZ喎"http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vcCAtJmd0OyBvbkRlc3Ryb3mho7PG1q7OqjxzdHJvbmc+ZW50aXJlIGxpZmV0aW1lPC9zdHJvbmc+oaM8L3A+DQo8cD4yLrWx1rTQ0G9uU3RhcnS72LX3t723qMqxo6xBY3Rpdml0eb+qyryxu9PDu6fL+bz7o6jSsr7NysfLtaOsb25DcmVhdGXKsdPDu6fKx7+0sru1vbTLQWN0aXZpdHm1xKOsxMfTw7unv7S1vbXEysfExLj2o7+1sci7yse0y0FjdGl2aXR51q7HsLXExMe49kFjdGl2aXR5o6mjrNK71rG1vW9uU3RvcNaux7CjrLTLvde2zkFjdGl2aXR5trzKx7G708O7p7/JvPujrLPG1q7OqjxzdHJvbmc+dmlzaWJsZSBsaWZldGltZTwvc3Ryb25nPqGjPC9wPg0KPHA+My61sda00NC1vW9uUmVzdW1lu9i197e9t6jKsaOsQWN0aXZpdHm/ydLUz+zTptPDu6e9u7ulo6zSu9axtb1vblBhdXNlt723qNaux7CjrLTLvde2zkFjdGl2aXR5s8bWrs6qPHN0cm9uZz5mb3JlZ3JvdW5kIGxpZmV0aW1lPC9zdHJvbmc+oaM8L3A+DQo8cD7U2sq1vMrTptPDs6G+sNbQo6y82cnoQSBBY3Rpdml0ec6709rVu7alo6y0y8qx08O7p7LZ1/ejrLTTQSBBY3Rpdml0ecz416q1vUIgQWN0aXZpdHmho8THw7S21EFCwLTLtaOsvt/M5bvhu9i198TE0KnJ+sP81tzG2tbQtcS3vbeoxNijv7vYtfe3vbeotcS+38zlu9i198uz0PLT1srH1PXDtNH5tcTE2KO/PC9wPg0KPHA+v6rKvMqxo6xBsbvKtcD9u6+jrNa00NC1xLvYtffT0EE6b25DcmVhdGUgLSZndDsgQTpvblN0YXJ0IC0mZ3Q7IEE6b25SZXN1bWWhozwvcD4NCjxwPrWx08O7p7Xju/dB1tCwtMWlwLS1vULKsaOsvNnJ6ELIq7K/1dq1stehwctBo6y9q9LAtM7WtNDQQTpvblBhdXNlIC0mZ3Q7IEI6b25DcmVhdGUgLSZndDsgQjpvblN0YXJ0IC0mZ3Q7IEI6b25SZXN1bWUgLSZndDsgQTpvblN0b3ChozwvcD4NCjxwPrTLyrHI57n7teO790JhY2u8/KOsvavSwLTO1rTQ0EI6b25QYXVzZSAtJmd0OyBBOm9uUmVzdGFydCAtJmd0OyBBOm9uU3RhcnQgLSZndDsgQTpvblJlc3VtZSAtJmd0OyBCOm9uU3RvcCAtJmd0OyBCOm9uRGVzdHJveaGjPC9wPg0KPHA+1sG0y6OsQWN0aXZpdHnVu9bQ1rvT0EGho9TaQW5kcm9pZNbQo6zT0MG9uPawtLz81NrTsM/sQWN0aXZpdHnJ+sP81tzG2tXiv+nQ6NKquPHN4sf4t9bPwqOsvLRCYWNrvPy6zUhvbWW8/KGjztLDx8/I1rG907+0z8LKtdHpveG5+6O6PC9wPg0KPHA+tMvKscjnufuwtM/CQmFja7z8o6zPtc2zt7W72LW918DD5qOssqLSwLTO1rTQ0EE6b25QYXVzZSAtJmd0OyBBOm9uU3RvcCAtJmd0OyBBOm9uRGVzdHJveaGjPC9wPg0KPHA+tMvKscjnufuwtM/CSG9tZbz8o6i3x7OksLSjqaOsz7XNs7e1u9i1vdfAw+ajrLKi0sC0zta00NBBOm9uUGF1c2UgLSZndDsgQTpvblN0b3Cho9PJtMu/ybz7o6xCYWNrvPy6zUhvbWW8/Nb30qrH+LHw1NrT2srHt/G74da00NBvbkRlc3Ryb3mhozwvcD4NCjxwPrTLyrHI57n7s6SwtEhvbWW8/KOssrvNrMrWu/q/ycTcta+z9rK7zazE2sjdo6xBY3Rpdml0ecn6w/zW3MbazrS3osn6seS7r6Oo08nQocPXMnOy4rXEo6yyu9aqtcDG5Mv7yta7+srHt/G74bbUQWN0aXZpdHnJ+sP81tzG2tPQ07DP7KOpoaM8L3A+DQo8cD7TydPaQW5kcm9pZLG+ye21xMzY0NSjrMq5tcPP1tTasrvJ2dOm08O2vMO709DWsb3Tzcuz9tOm08OzzNDytcS5psTco6ywtNXV0ruw47XEwt+8raOstbFBY3Rpdml0edW71tDT0MfS1rvT0NK7uPZBY3Rpdml0ecqxo6y1sbC0z8JCYWNrvPy0y0FjdGl2aXR5u+HWtNDQb25EZXN0cm95o6zEx8O0z8K0zrXju/e0y9Om08OzzM28seq9q7TT1tjQwsb0tq+jrNLytMujrLWxx7Cyu8nZ06bTw7PM0PK2vMrHssnIocjnSG9tZbz8tcTQp7n7o6y1sbXju/fBy0JhY2u8/KOsz7XNs7e1u9i1vdfAw+ajrMi7uvO147v306bTw7PM0PLNvLHqo6zWsb3Tu9i1vdaux7C1xEFjdGl2aXR5vefD5qOs1eLW1tCnufvKx9T1w7TKtc/WtcTE2KO/PC9wPg0KPHA+zai5/dbY0LSwtM/CQmFja7z8tcS72LX3uq/K/aOs16qzyUhvbWW8/LXE0Ke5+7y0v8mhozwvcD4NCjxwcmUgY2xhc3M9"brush:java;"> @Override public void onBackPressed() { Intent home = new Intent(Intent.ACTION_MAIN); home.addCategory(Intent.CATEGORY_HOME); startActivity(home); }

当然,此种方式通过Home键效果强行影响到Back键对Activity生命周期的影响。注意,此方法只是针对按Back键需要退回到桌面时的Activity且达到Home效果才重写。

或者,为达到此类效果,Activity实际上提供了直接的方法。

1 activity.moveTaskToBack(true);
moveTaskToBack()此方法直接将当前Activity所在的Task移到后台,同时保留activity顺序和状态。

在之前的项目开发过程中,当时遇到一个很奇怪的问题:手机上的“开发者选项”中有一个“不保留活动”的设置,当开启此设置,手机上的设置提示是“用户离开后即销毁每个活动”,开启后,对于其他的应用程序是从A Acticity到B Activity,然后Back键回到A,此时,其他应用程序只是先白屏(有可能黑屏等,取决于主题设置)一下,然后A开始可见,但是我的应用程序中出现的一个结果却是直接返回到了桌面。一开始百思不得其解。最后终于定位出问题。首先,我们需要明确开启此设置项后对Activity生命周期的影响。开启此设置项后,当A到B时,假设B全部遮挡住了A,将依次执行A:onPause -> B:onCreate -> B:onStart -> B:onResume -> A:onStop -> A:onDestroy。是的,A在系统原本的生命周期回调中增加了onDestroy。此即“用户离开后即销毁每个活动”的含义。但此时需要注意的是,只要没有认为的调用A的finish()方法,虽然A执行了onDestroy,但Activity栈中依然保留有A,此时B处于栈顶。那么在B中按Back键回到A时,将依次执行:B:onPause -> A:onCreate -> A:onStart -> A:onResume -> B:onStop -> B:onDestroy。没错,A从onCreate开始执行了。此处也就解释了为什么A可能会出现白屏(或黑屏等)一下的原因了。此处的意思是,只要从onCreate开始执行,就会先出现白屏或黑屏的情况。

那么为什么我的应用程序会跟其他应用程序出现不一样呢?最后定为出问题在于当时我的应用程序中为了做到完全退出应用程序效果,专门使用了一个Activity栈去维护Activity(当时是借鉴了网上的此类实现方案,现在想想,实在没必要,且不说Android本身特性决定了没必要通过如此方法去达到退出效果,仅仅是此方法本身也存在很大的问题,现在在网上依然能见到有不少文章说到应用程序退出可以使用此方法,哎。。),在onCreate中入栈,onDestroy出栈,调用了如下方法:

1 // 结束Activity&从堆栈中移除
2 AppManager.getAppManager().finishActivity(this);
其中,AppManager中finishActivity函数具体定义是:

复制代码

 1 /**
 2  * 结束指定的Activity
 3  */
 4 public void finishActivity(Activity activity) {
 5     if (activity != null) {
 6         activityStack.remove(activity);
 7         activity.finish();
 8         activity = null;
 9     }
10 }

复制代码
至此,相信大家应该看出问题的所在了吧。

没错,问题在于执行了activity的finish()方法!! activity的finish()方法至少有两个层面含义,1.将此Activity从Activity栈中移除,2.调用了此Activity的onDestroy方法。对于不开启“不保留活动”的设置项,实际上也没什么影响,但是一旦开启此设置,问题显露无疑。开启此此设置后,正常情况下离开A,即使执行了A的onDestroy,Activity栈中还是有A的,但是我这样写后,finish()方法一执行,Activity栈中就没有A了,因此,当点击Back键时,Activity栈中已经没有此应用的任何Activity了,直接来到了手机桌面。

可能,有些人会说,我就是要通过此种方法想去完全退出应用程序,同时希望自己的Activity栈和系统中Activity栈保持一致,怎么办呢?

在此,可以通过如下改写去实现:

复制代码

/**
* 结束指定的Activity
 */
public void finishActivity(Activity activity) {
    if (activity != null) {
    // 为与系统Activity栈保持一致,且考虑到手机设置项里的"不保留活动"选项引起的Activity生命周期调用onDestroy()方法所带来的问题,此处需要作出如下修正
    if(activity.isFinishing()){
        activityStack.remove(activity);
        //activity.finish();
        activity = null;
    }
    }
}

复制代码

以此谨记!


此外,对于不同的启动模式或Intent Flags或操作行为(如横竖屏切换)等有可能会影响到Activity生命周期,此类问题将放在后续相关文章中进行总结。

相关文章
最新文章
热点推荐