[Android]Activity生命周期+启动模式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Gods_magic/article/details/84677534

Activity是一个与用户交互的接口。


一、Activity生命周期

 1.Activity的4种状态

     Active  Paused  Stopped  killed

  1. Active:当前Activity正处在运行状态,即当前Activity获取了焦点。
  2. Paused:当前Activity正处在暂停状态,即当前Activity失去了焦点。此时Acticity并没有被销毁,内存里面的成员变量,状态信息等仍然存在,当然这个Activity也仍然可见,但是焦点却不在它身上,比如被一个对话框形式的Activity获取了焦点,或者被一个透明的Activity获取了焦点,这都能导致当前的Activity处于paused状态。
  3. Stopped:与paused状态相似,stopped状态的Activity是完全不可见的,但是内存里面的成员变量,状态信息等仍然存在,但是也没有被销毁。
  4. Killed:已经被销毁的Activity才处于killed状态,它的内存里面的成员变量,状态信息等都会被一并回收。

 2.Activity生命周期分析 

    

  •  onCreate :该方法是在Activity被创建时回调,它是生命周期第一个调用的方法,在创建Activity时需要重写该方法,在该方法中做一些初始化的操作,如通过setContentView设置界面布局的资源,初始化所需要的组件信息等。
  • onStart :Activity已经可见,但是还没有出现在前台,无法与用户进行交互。这个时候通常Activity已经在后台准备好了,但是就差执行onResume()函数出现在前台。
  • onResume :Activity已在前台可见,可与用户交互了(处于Active/Running形态)。当Activity停止后(onPause方法和onStop方法被调用),重新回到前台时也会调用onResume方法,因此我们也可以在onResume方法中初始化一些资源,比如重新初始化在onPause或者onStop方法中释放的资源。 
  • onPause :此方法被回调时则表示Activity正在停止(Paused形态) 此方法被回调时则表示Activity正在停止(Paused形态),当启动其他的acitivty时,此时当前activity会进入到onPouse()方法中,当前activity是可见的,但不能与用户交互状态。 
  • onStop :一般在onPause方法执行完成直接执行,表示Activity即将停止或者完全被覆盖(Stopped形态),此时Activity不可见,仅在后台运行。应该在此函数中做一些不那么耗时的轻量级回收操作。
  • onRestart :表示Activity正在重新启动,当Activity由不可见变为可见状态时,该方法被回调。这种情况一般是用户打开了一个新的Activity时,当前的Activity就会被暂停(onPause和onStop被执行了),接着又回到当前Activity页面时,onRestart方法就会被回调。 
  • onDestroy :此时Activity正在被销毁,也是生命周期最后一个执行的方法,一般我们可以在此方法中做一些回收工作和最终的资源释放。 Activity接下来面对的是被GC回收,宣告生命终结。
  • onPause 后直接执行onResume 的情况,请参考:https://blog.csdn.net/a872822645/article/details/62217965
  • 更多Activity生命周期情况分析,请参考:https://blog.csdn.net/clandellen/article/details/79257489

二、Activity启动模式

 1.Android任务栈

         任务栈与Activity的启动模式密不可分,它是用来存储Activity实例的一种数据结构,Activity的跳转以及回跳都与这个任务栈有关。启动一个Activity后,这个Activity实例就会被放入任务栈中,当点击返回键的时候,位于任务栈顶层的Activity就会被清理出去,当任务栈中不存在任何Activity实例后,系统就回去回收这个任务栈。

 2.启动模式

Activity的启动模式有4种,分别是:standard | singleTop | singleTask | singleInstance

(1)系统默认的启动模式Standard 

标准模式,这也是系统的默认模式。每次启动一个Activity都会重新创建一个新的实例,不管这个实例是否存在。被创建的实例的生命周期符合典型情况下的Activity的生命周期。在这种模式下,谁启动了这个Activity,那么这个Activity就运行在启动它的那个Activity的任务栈中。比如Activity A启动了Activity B(B是标准模式),那么B就会进入到A所在的任务栈中。有个注意的地方就是当我们用ApplicationContext 去启动standard模式的Activity就会报错,这是因为standard模式的Actiivty默认会进入启动它的Activity所属的任务栈中,但是由于非Activity类型的Context(如ApplicationContext)并没有所谓的任务栈,所以这就会出现错误。解决这个问题的方法就是为待启动的Activity指定FLAG_ACTIVITY_NEW_TASK标记位,这样启动的时候就会为它创建一个新的任务栈,这个时候启动Activity实际上以singleTask模式启动的

(2)栈顶复用模式:SingleTop

在这种模式下,如果新的Activity已经位于任务栈的栈顶,那么此Activity不会被重新创建,同时它的onNewIntent方法被回调,通过此方法的参数我们可以取出当前请求的信息。需要注意的是,这个Activity的onCreate,onStart不会被系统调用,因为它并没有发生改变。如果新的Activity已经存在但不是位于栈顶,那么新的Activity仍然会重新重建。举个例子,假设目前栈内的情况为ABCD,其中ABCD为四个Activity,A位于栈低,D位于栈顶,这个时候假设要再次启动D,如果D的启动模式为singleTop,那么栈内的情况依然为ABCD;如果D的启动模式为standard,那么由于D被重新创建,导致栈内的情况为ABCDD。

(3)栈内复用模式:SingTask

这是一种单例实例模式,在这种模式下,只要Activity在一个栈中存在,那么多次启动此Activity都不会重新创建实例,和singleTop一样,系统也会回调其onNewIntent。具体一点,当一个具有singleTask模式的Activity请求启动后,比如Activity A,系统首先寻找任务栈中是否已存在Activity A的实例,如果已经存在,那么系统就会把A调到栈顶并调用它的onNewIntent方法,如果Activity A实例不存在,就创建A的实例并把A压入栈中。

  •  比如目前任务栈S1的情况为ABC,这个时候Activity D以singleTask模式请求启动,其所需的任务栈为S2,由于S2和D的实例均不存在,所以系统会先创建任务栈S2,然后再创建D的实例并将其投入到S2任务栈中。
  • 另外一种情况是,假设D所需的任务栈为S1,其他情况如同上面的例子所示,那么由于S1已经存在,所以系统会直接创建D的实例并将其投入到S1。
  • 如果D所需的任务栈为S1,并且当前任务栈S1的情况为ADBC,根据栈内复用的原则,此时D不会重新创建,系统会把D切换到栈顶并调用其onNewIntent方法,同时由于singleTask默认具有clearTop的效果,会导致栈内所有在D上面的Activity全部出栈,于是最终S1中的情况为AD。

(4)单实例模式:SingleInstance 

这是一种加强的singleTask模式,它除了具有singleTask模式所有的特性外,还加强了一点,那就是具有此种模式的Activity只能单独位于一个任务栈中,换句话说,比如Activity A是singleInstance模式,当A启动后,系统会为它创建一个新的任务栈,然后A独自在这个新的任务栈中,由于栈内复用的特性,后续的请求均不会创建新的Activity,除非这个独特的任务栈被系统销毁了。

  •  以singleInstance模式启动的Activity具有全局唯一性,即整个系统中只会存在一个这样的实例。
  • 以singleInstance模式启动的Activity在整个系统中是单例的,如果在启动这样的Activiyt时,已经存在了一个实例,那么会把它所在的任务调度到前台,重用这个实例。
  • 以singleInstance模式启动的Activity具有独占性,即它会独自占用一个任务,被他开启的任何activity都会运行在其他任务中。
  • 被singleInstance模式的Activity开启的其他activity,能够在新的任务中启动,但不一定开启新的任务,也可能在已有的一个任务中开启。

总结:

 上面介绍了4种启动模式,这里需要指出一种情况,我们假设目前有2个任务栈,前台任务栈的情况为AB,而后台任务栈的情况为CD,这里假设CD的启动模式均为singleTask。现在请求启动D,那么整个后台任务栈都会被切换到前台,这个时候整个后退列表变成了ABCD。当用户按back键的时候,列表中的Activity会一一出栈,如下图所示:

前台任务栈:就是指和用户正在交互的应用程序所在的任务栈。

后台任务栈:就是指处于后台的应用程序所在的任务栈。

  如果不是请求的D而是请求的C,那么情况就不一样了,如下图所示:


注:大部分参考文章:https://blog.csdn.net/clandellen/article/details/79257489  

Activity与Service通信方式:https://blog.csdn.net/Gods_magic/article/details/84558169

猜你喜欢

转载自blog.csdn.net/Gods_magic/article/details/84677534