`
qilixiang012
  • 浏览: 202635 次
文章分类
社区版块
存档分类
最新评论

Android四大组件的生命周期

 
阅读更多

一、Activity











方法

描述

是否可以终止

下一个方法

onCreate()

Activity程序启动之后会首先调用此方法。在这个方法体里,你需要完成所有的基础配置——创建视图,连接数据库并将数据绑定到list列表中,等等。这个方法会传递一个保存了此Activity上一状态信息的Bundle对象。紧随其后的方法总是onStart().

不可以

onStart()

onRestart()

处于停止态的Activity调用此方法,可以让此Activity重新显示在前台。

紧随其后的方法总是onStart()

不可以

onStart()

onStart()

在此Activity可见(显示在前台)之前调用。

如果接着是显示在前台,紧随其后的方法是onResume()如果接下来此Activity被隐藏了,则紧随其后的方法是onStop()

不可以

onResume()

onStop()

onResume()

在与用户进行交互之前调用此方法,这一时刻Activity位于activity栈的栈顶,在等待用户的操作(输入数据或点击按钮等)。紧随其后的方法是onPause().

不可以

onPause()

onPause()

当启动其他activity时调用此方法。在这个方法体里,通常用于提交未保存的数据、停止动画/视频和处理其他占用CPU资源的程序,等等。同时在这个方法体里处理的都是一些迅速快捷的操作,因为下一个activity会在onPause()方法执行完之后才可以在前台显示

如果此Activity重新回到前台显示,则紧随其后的方法是onResume();如果此Activity变得不可见了,则紧随其后的方法是onStop()

可以

onResume()

onStop()

onStop()

Activity不可见时调用此方法。这个方法的调用时刻是在Activity需要销毁或者被其他otherActivity取代且覆盖此Activity在前台显示时调用。

如果此Activity重新显示在前台,紧随其后的方法是onRestart();如果此Activity需要被销毁,紧随其后的方法是onDestroy()

可以

onRestart()

onDestroy()

onDestroy()

Activity被销毁时调用此方法。这是Activity生命周期里最后调用的一个方法。这个方法的调用可以发生在activity调用了finish()方法之后,或者是系统为了节省空间而销毁了此Activity的实例。你可以使用isFinishing()方法来区分这两种情况。

可以

——

在谈Activity生命周期之前先谈下Activity栈:

Activity栈保存了已经启动并且还没有终止的所有的Activity,并且我们知道栈是遵从“后进先出”的规则,那么Activity栈同样也遵从这样的规则。

Activity的状态与其在Activity栈的位置有着密切的关系。不仅如此,Android系统在资源不足时,也是通过Activity栈来选择哪些Activity是可以被终止的,一般来讲,Activity系统会优先选择终止处于目前是停止状态并且比较靠近Activity栈底的Activity。

1. Activity4种状态

Activity的生命周期指Activity从启动到销毁的过程,Activity有4种状态 :

(1)活动(Active)状态:这时候Activity处于栈顶,且是可见的,有焦点的,能够接收用户输入前 景Activity。Runtime将试图不惜一切代价保持它活着,甚至杀死其他Activity以确保它有它所需的资源。当另一个Activity变成Active时,当前 的将变成Paused状态。

(2)暂停(Paused)状态:在某些情况下,你的Activity是可见的,但没有焦 点,在这时候,Actvity处于Paused状态。例如,如果有一个透明或非全屏幕上的Activity在你的Actvity上面,你的 Activity将。当处于Paused状态时,该Actvity仍被认为是Active的,但是它不接受用户输入事件。在极端情况下,Runtime将杀死Paused Activity,以进一步回收资源。当一个Actvity完全被遮住时,它将进入Stopped状态。

(3)停止(Stopped)状态:当Activity是不可见的时,Activity处于Stopped状态。Activity将继续保留在内存中保持当前的所有状态和成员信息,假 设系统别的地方需要内存的话,这时它是被回收对象的主要候选。当Activity处于Stopped状态时,一定要保存当前数据和当前的UI状态,否则一 旦Activity退出或关闭时,当前的数据和UI状态就丢失了。

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

2. Activity的生命周期

(1)全生命周期:

全生命周期是从Activity建立到销毁的全部过程,始于onCreate(),结束于onDestroy()。开发者通常在onCreate()中初始化用户界面,分配引用类变量,绑定数据控件,并创建服务和线程等Activity所能使用的全局资源和状态,并在onDestroy()中释放这些资源,并确保所有外部连接被关闭,如网络或数据库的连接等;在一些极端情况下,Android系统会直接终止进程,而不会先调用onDestroy()。

为了避免创造短期对象和增加垃圾收集的时间,以致对用户体验产生直接影响。如果你的Activity需要创建一些对象的话,最好在onCreate方法中创建,因为它在一个Activity的完整生命周期中只被调用一次。

使用OnCreate方法来初始化你的Activity:初始化的用户界面,分配引用类变量,绑定数据控件,并创建服务和线程。在OnCreate方法传 递的对象Bundle包含最后一次调用onSaveInstanceState保存的UI状态。你可以使用这个Bundle恢复用户界面到以前的状态,无 论是在OnCreate方法或通过覆盖onRestoreInstanceStateMethod方法。
覆盖onDestroy方法来清理OnCreate中创建的任何资源,并确保所有外部连接被关闭,例如网络或数据库的联系。
为了避免创造短期对象和增加垃圾收集的时间,以致对用户体验产生直接影响。如果你的Activity需要创建一些对象的话,最好在onCreate方法中创建,因为它仅调用一次在一个Actvity的完整生命周期中。

  • 例如:某个Activity有一个在后台运行的线程,用于从网络下载数据,则该Activity可以在onCreate()中创建线程,在onDestory()中停止线程

(2)可视生命周期:

可视生命周期是Activity在界面上从可见到不可见的过程,开始于onStart(),结束于onStop()。在极端情况下,系统会直接销毁一个Activity,而不先调用onStop,即使它处于可见状态。在这个时间里,活动对用户是可见的,但是它有可能不具有焦点,或者它可能被部分遮住了。在一个Activity完整的生命周期中可能会经过几个Activity可见的生命周期,因为你的Activity可 能会经常在前台和后台之间切换。在极端情况下,Runtime将杀掉一个Activity即使它在可见状态并且并不调用onStop方法。

  • OnStop方法用于暂停或停止动画,线程,定时器,服务或其他专门用于更新用户界面程序。当用户界面是再次可见时,使用OnStart(或onRestart)方法来恢复或重新启动这些程序,。

  • onRestart方法优先于onStart被调用当一个Activity被重现可见时,使用它你可以实现一些Activity重新可见时的特殊的处理。

  • 例如:可以在onStart中注册一个Intent Receiver来监听数据变化导致UI的变动,当不再需要显示时候,可以在onStop()中注销它。onStart(),onStop()都可以被多次调用,因为Activity随时可以在可见和隐藏之间转换。

  • OnStart / OnStop方法也被用来注册和注销专门用于更新用户界面Intent接收者。

(3)活动(前台)生命周期

活动生命周期是Activity在屏幕最上层,并能够与用户交互的阶段,并且正在接收用户的输入事件。开始于onResume(),结束于onPause()。在Activity的状态变换过程中onResume()和onPause()经常被调用,因此这两个方法中的代码应该写得简单、高效些,以提高性能,以保证在前台和后台之间进行切换的时候应用能够保持响应。当一个新的Actvity启 动,或该设备进入休眠状态,或失去焦点,Activity活跃的生命周期就结束。

  • 尽量在onPause和onResume方法中执行较量轻的代码以确保 您的应用程序能够快速响应Acitvity在前台和后台之间切换。

  • 在调用onPause之前,onSaveInstanceState会被调用。这个方法提供了一个机会保存当前的UI状态到Bundle当中。 Bundle信息将会被传递到OnCreate和onRestoreInstanceState方法。使用onSaveInstanceState保存 UI状态(如检查按钮状态,用户焦点,未提交用户输入)能够确保目前相同的用户界面当Activity下次被激活时。在Activity活跃生命周期中, 你可以安全地认onSaveInstanceState和onPause将被调到即使当前进程将终止。

总的来说,在生命周期里通过重写Activity生命周期回调方法,你可以监控以上三个嵌套的方法循环。

3. Activity的启动模式

Activity有4种启动模式,类似于C语言中的局部变量、全局变量及静态变量等。

(1)standard:标准模式,调用startActivity()方法都就会产生一个新的实例。并将该Activity增加到当前Task栈中——这种模式不会启动新的Task,新的Activity将被增加到原有的Task中。这种方式用一个词来形容的话就是“拿来主义”。

(2)singleTop:检查是否已经存在一个实例位于Activity Stack的顶部,如果存在就不产生新的实例,否则调用Activity的newInstance()方法产生一个新实例,因此,singleTop模式的思想便是“拒绝堆叠”。

——这种模式不会启动新的Task

(3)singleTask:采用这种加载模式的Activity在同一个Task内只有一个实例,当系统采用singleTask模式启动目标Activity时,可分为如下三种情况:“独立门户”。

如果将要启动的目标Activity不存在,系统将会创建目标Activity的实例,调用本应用的singleTask的Activity将它加入原来的Task栈顶,调用非本应用的singleTask的Activity则新建一个Task将singleTask的Activity加入新建Task的栈顶

如果将要启动的目标Activity已经位于Task栈顶,此时与singleTop模式的行为相同。

如果将要启动的目标Activity已经存在,但没有位于Task栈顶,系统将会把位于该Activity上面的所有Activity移出Task栈,从而使得目标Activity转入栈顶。即如果Activity发现已经存在时,会销毁其上的Activity,然后调用onNewIntent。(不管是调用其他应用的singleTask的Activity还是本应用的singleTask的Activity)。

建议:如果该Activity的类型不是LAUNCHER,最好不要设为singleTask。避免称为“孤岛”。
用处:那么singleTask的这些特性有什么用处?我们举一个例子,浏览器就是一个singleTask的例子,启动一个浏览器,在Android中是一个比较沉重的过程,它需要做很多初始化的工作,并且会有不小的内存开销。如果有多个应用都来请求打开网页,那么系统就不会不堪重负。因此,如果浏览器采用singleTask模式,如果有多个请求打开网页的请求,都会在一个Task中响应,这样就会避免以上的情况。

SingleTask的例子:浏览器的browser activity设置了SingleTask只运行在它自己的task中,如果Browser的task现在正在后台当中(task B),而我们的app(task A)的正要打开这个activity,这个task就会被直接移到前台接收我们的intent。

返回键只会将界面返回到当前task的下一个activity,所以Task B回到前台后,返回键会先作用在Task B中,直到最后一个activity被弹出,才会回到我们的Task A栈顶的activity。

(4)singleInstance:这种加载模式下,系统保证无论从哪个Task中启动目标Activity,只会创建一个目标Activity实例,并会使用一个全新的Task栈来装载该Activity实例。 当系统采用singleInstance模式启动目标Activity时可分为如下两种情况:“孤独寂寞”

如果将要启动的目标Activity不存在,系统会先创建一个全新的Task,再创建目标Activity的实例,并将它加入新的Task的栈顶。

如果将要启动的目标Activity已经存在,无论它位于哪个应用程序中,无论它位于哪个Task中,系统将会把该Activity所在的Task转到前台,从而使用该Activity显示出来。

“拿来主义”standard模式。哪里需要调用我我就去哪里,可以多次实例化,可以几个相同的Activity重叠。

“拒绝堆叠”singleTop模式。可以多次实例化,但是不可以多个相同的Activity重叠,当堆栈的顶部为相同的Activity时,会调用onNewIntent函数。

“独立门户”singleTask模式。同一个应用中调用该Activity时,如果该Activity没有被实例化,会在本应用程序的Task内实例化,如果已经实例化,会将Task中其上的Activity销毁后,调用onNewIntent;其它应用程序调用该Activity时,如果该Activity没有被实例化,会创建新的Task并实例化后入栈,如果已经实例化,会销毁其上的Activity,并调用onNewIntent。一句话,singleTask就是“独立门户”,在自己的Task里,并且启动时不允许其他Activity凌驾于自己之上。

“孤独寂寞”singleInstance模式。加载该Activity时如果没有实例化,他会创建新的Task后,实例化入栈,如果已经存在,直接调用onNewIntent,该Activity的Task中不允许启动其它的Activity,任何从该Activity启动的其他Activity都将被放到其他task中,先检查是否有本应用的task,没有的话就创建。


4. Activity的生命周期方法

与其它编程范例里的 main() 方法不一样, android 在 activity 实例里的启动是通过调用一系列的回调方法,每一个回调方法都对应于生命周期中特定的状态。开启或者销毁一个activity 对通过一系列的 回调方法来实现。

0.onCreate():

这是必须实现的回调方法,启动一个activity时会首先调用此方法。因此,在onCreate()的方法体里,你应该初始化该activity必要的控件。值得注意的是,在这里你必须调用setContentViewViewview)方法去呈现用户的界面。

1. onStart()

onStart() 方法与 onStop() 方法是相对应的,因为不管是第一次创建还是从stopped 状态恢复回来都要调用 onStart();

在onStart 方法里可以检测一些系统特征是否有效果,比如

 @Override
protectedvoid onStart(){
    super.onStart();  // Always call the superclass method first
    
    // The activity is either being restarted or started for the first time
    // so this is where we should make sure that GPS is enabled
    LocationManager locationManager = 
            (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    boolean gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    
    if(!gpsEnabled){
        // Create a dialog here that requests the user to enable GPS, and use an intent
        // with the android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS action
        // to take the user to the Settings screen to enable GPS when they click "OK"
    }}@Overrideprotectedvoid onRestart(){
    super.onRestart();  // Always call the superclass method first
    
    // Activity being restarted from stopped state    }

2. onPause()

Called when the system is about to start resuming another activity. This method is typically used tocommit unsaved changes to persistent data,stop animations and other things that may be consuming CPU, and so on. It should do whatever it does veryquickly, because the next activity will not beresumed until it returns.

比如记录用户的视频播放点,草稿邮件等一些重要的东西都应该在 onPause() 里保存,因为 onPause(), onStop(), onDestory() 这三个方法中的任意一个被执行完后 activity 所在的 process 都有可能被系统杀死(比如为了恢复系统内存)。通常在这样的状态下,你需要处理用户数据的提交、动画处理等操作。

3. onStop()

基本上我们应该在 onStop() 方法里清除释放所有可能会导致 内存泄漏的 activity 资源;因为 onDestory() 可能不被执行,而又不太适合在 onPause() 里做太多的事情。

Although the onPause() method is called before onStop(), you should use onStop() to perform larger,

more CPU intensive shut-down operations, such as writing information to a database.

4. onDestory()

onDestory() 是 activity 生命周期里最后一个 回调方法,所以onDestory() 是我们释放那些有可能导致内存泄漏的资源;

通常在 onCreate() 里创建的后台 / 额外的线程对象,以及其它的 long-running actions like method tracing 都应该在 onDestory() 里得到释放。

5.onSaveInstanceState()

onSaveInstanceState() 在 onPause() 之前被调用;

onRestoreInstanceState() 在 onStart() 之后被调用,且只有 Bundle savedInstanceState 不为空时才被系统调用;

 Activity的 onSaveInstanceState() 和 onRestoreInstanceState()并不是生命周期方法,它们不同于 onCreate()、onPause()等生命周期方法,它们并不一定会被触发。

可参考http://www.cnblogs.com/hanyonglu/archive/2012/03/28/2420515.html

6.

如果在 onCreate() 里调用 finish() 方法会直接调用 onDestory() 方法;

1) 启动Activity:onCreate()->onStart()->onResume()->Activity is running

2) 按back键返回:onPause()->onStop()->onDestroy() 再次启动时:onCreate()->onStart()->onResume()->Activity is running

3). 按home键返回:onPause()->onStop() 再次启动时:onRestart()->onStart()->onResume()->Activity is running

4) 切换到别的Activity(当前Activity不finish),或者采用这个,启动程序进入Activity,按Home键进入桌面,然后长按Home建点击该应用重新进入Activity:onPause()->onStop() 再次启动时:onRestart()->onStart()->onResume()->Activity is running


5) 切换到别的Activity(当前Activity finish): onPause()->onStop()->onDestroy() 再次启动时:onCreate()->onStart()->onResume()->Activity is running

6)然后按挂机键,进入锁屏界面,然后从锁屏界面返回Activity:onPause()->onResume()

7)切换到另一个Activity对话框界面,然后按返回键返回原来的Activity:onPause()->onResume()

8)启动本Activity中创建的对话框(弹出Toast和AlertDialog),按返回键从Dialog返回:Activity的状态始终未变

9)无论现在是onPause状态还是onStop状态,当系统的内存不足时,都会将该Activity杀死,当再次进入该Activity重新创建。这意味着,如果发生这种情况,可能我们的onDestroy(如果在停止状态被杀死),甚至是onStop都没有得到执行(如果在暂停状态被杀死),因此,一些重要的数据和状态,需要在这种情况下也得到保存,Google为我们专门提供了一个回调函数,就是onSaveInstanceState(Bundle),通过该函数,可以将这些重要的数据在销毁前进行保存,然后再onCreate时重新读

10)横竖屏切换时候activity的生命周期:

1、不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次

2、设置Activity的android:configChanges="orientation"时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次

3、设置Activity的android:configChanges="orientation|keyboardHidden"时,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法

11)当在MainActivity中按back键,退出时,或者在代码中调用finish(),finishActivity()方法最终就会走到onDestory()。

tips

在多数情况下,你是不需要显式地调用finish…()方法去销毁一个activity。在将要讨论到的activity生命周期里,你可以知道,Android系统会为你管理activity的生命周期,所以你并不需要显式销毁activity(即调用finish类方法)。显式地调用finish类方法,会对用户的体验产生不利的影响,除非你确实是不希望用户返回到此activity(界面),才去显式调用finish类方法。


二、Service



在Service每一次的开启关闭过程中,只有onStart可被多次调用(通过多次startService调用),其他onCreate,onBind,onUnbind,onDestory在一个生命周期中只能被调用一次。

三、BroadcastReceive

生命周期只有十秒左右,如果在 onReceive() 内做超过十秒内的事情,就会报ANR(Application No Response) 程序无响应的错误信息。

一个BroadcastReceiver 对象只有在被调用onReceive(Context, Intent)的才有效的,当从该函数返回后,该对象就无效的了,结束生命周期。

因此从这个特征可以看出,在所调用的onReceive(Context, Intent)函数里,不能有过于耗时的操作,不能使用线程来执行。对于耗时的操作,请start service来完成。因为当得到其他异步操作所返回的结果时,BroadcastReceiver 可能已经无效了。

四、ContentProvider



分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics