Activity的启动模式详解

来源:互联网 发布:nginx 配置多个域名 编辑:程序博客网 时间:2024/06/05 17:25

首先说一下Activity为什么需要启动模式。我们知道,在默认情况下,当我们多次启动同一个Activity的时候,系统就会创建多个实例并把他们一一放入任务栈中,当我们点击back键的时候,会发现这些Activity就会一一退栈,知道栈空为止,当栈中无任何Activity的时候,系统就会回收这个任务栈。多次启动同一个Activity,系统就会重复创建多个相同实例,这是不是很不好?系统为我们提供了四种启动模式来修改系统的默认行为。目前系统中有四种启动模式:standard、singleTop、singleTask和singleInstance。
在介绍Activity的启动模式之前,首先介绍一下安卓中任务栈的概念。这需要先从一个参数说起:TaskAffinity,可以翻译为任务相关性。这个参数标识了一个Activity所需要的任务栈的名字,默认情况下,所有Activity所需的任务栈的名字为应用的包名。当然我们也可以单独为每个Activity制定该属性的值。但这个属性不能喝包名相同,如果相同,等于没有制定。TaskAffinity这个属性主要和singleTask启动模式配对使用。其他情况下没有意义。任务栈分为前台任务栈和后台任务栈。后台任务栈中的Activity位于暂停状态,用户可以通过切换将后台任务栈再次调到前台。
(1)standard:标准模式,这是系统的默认模式。每次启动一个Activity就会创建这个Activity的实例,不管这个Activity实例是不是已经存在。一个任务栈中可以有多个实例,每个实例可以属于不同的任务栈。在这种模式下,谁启动了这个Activity,那么这个Activity就运行在启动它的那个Activity的任务栈中。当我们用ApplicationContext去启动standard模式的Activity即(getApplicationContext().startActivity(intent);),
就会报错,错误如下:
android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag.
这是因为standard模式的Activity默认会进入启动它的Activity所属的任务栈,但是由于非Activity类型的Context并没有所谓的任务栈,所以就会报错。在报错中,系统也为我们提供了解决的方法,就是为待启动的Activity制定FLAG_ACTIVITY_NEW_TASK,代码如下:
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
这样启动的时候机会为他创建一个新的任务栈,这个时候待启动的Activity实际上是以singleTask模式来启动的。
(2):singleTop:栈顶复用模式。在这种模式下,如果新Activity已经位于任务栈的栈顶,那么此Activity就不会被重新创建,同时它的onNewIntent方法会被调用,通过此方法的参数我们可以取出当前请求的信息。同时我们需要注意的是,这个Activity的onCreate,onStart方法不会被系统重新调用,因为他并没有发生改变。如果新的Activity已经存在但不是位于栈顶,那么新的Activity依然会被创建。
(3)singleTask:栈内复用模式,是一种单实例模式,在这种模式下,只要栈中存在新创建的Activity,那么这个Activity就不会被重新创建。和singleTop一样,系统同样会调用onNewIntent方法。当一个具有singleTask模式的Activity请求启动后,比如Activity A,系统首先会寻找是否存在A想要的任务栈,如果不存在A想要的任务栈,就会重新创建一个任务栈,然后创建A的实例压入栈中,如果开始存在A所需要的任务栈,再看现在A的实例是否在该任务栈中,如果该任务栈中不存在A的实例,就会重新创建A的实例放入任务栈中,如果此前任务栈中存在A的实例但此时A的实例不处于任务栈的栈顶,就会让A上面的实例统统出栈。如果此前任务栈中存在A的实例但此时A的实例处于栈顶,即和singleTop一样,不会创建新的实例。
(4)singleInstance:单实例模式。可以看做它是一种加强的singleTask实例。它除了具有singleTask所有的特性外,还加强了一点,就是此种模式的Activity只能单独的处于一个任务栈中。假设Activity A是singleInstance模式,当A启动后,系统会为他创建一个新的任务栈,然后A独自在这个新的任务栈中,由于栈内复用的特性,后续的请求均不会创建新的Activity,除非这个独特的任务栈被销毁了。

Activity中的Flags:表示标记位,标记位的作用很多,有的标记位可以设定Activity的启动模式。
FLAG_ACTIVITY_NEW_TASK:这个标记位的作用是为Activity制定“singleTask”模式。
FLAG_ACTIVITY_SINGLE_TOP:这个标记位的作用是为Activity制定“singleTop”模式。
FLAG_ACTIVITY_CLEAR_TOP:具有此标记位的Activity,当他启动时,在同一个任务栈中所有位于它上面的Activity都要出栈。

0 0
原创粉丝点击