Activity的启动模式---总结

Activity有四种启动模式:

1.standard(标准)    2.singleTop    3.singleTask  4.singleInstance

标识某个Activity的启动模式,有两种方式:

1.一种是通过AndroidManifest.xml    2.一种是通过Intent的标识

通过AndroidManifest.xml来标识:

  1. <activity android:name=".Activity1"
  2. android:launchMode="standard"
  3. android:label="@string/app_name">
  4. <intent-filter>
  5. <action android:name="android.intent.action.MAIN" />
  6. <category android:name="android.intent.category.LAUNCHER" />
  7. </intent-filter>
  8. </activity>

通过Intent的Flag来标识:

FLAG_ACTIVITY_NEW_TASK

FLAG_ACTIVITY_SINGLE_TOP

FLAG_ACTIVITY_CLEAR_TOP

-------------------------------------------------------------------------------------------------------------------------------------

standard模式

"standard" (the default mode)
Default. The system creates a new instance of the activity in the task from which it was started and routes the intent to it. The activity can be instantiated multiple times, each instance can belong to different tasks, and one task can have multiple instances.

比如,Activity1的启动模式是standard,那么,通过Intent去启动Activity1的时候,不管当前的task中是否包含了Activity1,也不管当前的栈顶中是否有Activity1,总之,系统会创建一个新的Activity1对象。

实验的例子:

AndroidManifest.xml里Activity的设置如下:

<activity

android:name="com.testlaunchemode.activity.ActivityStandard"

android:launchMode="standard"

/>

     代码如下:

public class ActivityStandard extends Activity {

private TextView tv ;

public void onCreate(Bundle state) {

super.onCreate(state);

              setContentView(R.layout. standard_activity);

              MyApp app = (MyApp) getApplicationContext();

tv = (TextView) findViewById(R.id. tv_result);

tv.setText( "Activity launched in standard mode,This is times result from Application: "

                           + app.inCreaseTimes());

       }

public boolean onTouchEvent(MotionEvent event) {

              Intent intent = new Intent(this , ActivityStandard.class);

              startActivity(intent);

return super .onTouchEvent(event);

       }

}

每次点击ActivityStandard的界面,就会再次生成一个新的ActivityStandard对象。

这个,可以通过,我们按返回按钮得到的效果来证实。我们,按下返回按钮时,会不断返回到上一个Activity,而上一个Activity的外观跟ActivityStandard的外观是一样的。由此,可以得出,是不断创建ActivityStandard。

如果点击四次,进来的时候那个ActivityStandard不是通过点击触发的,那么,在task中,在栈中就是:

ActivityStandard

ActivityStandard

ActivityStandard

ActivityStandard

ActivityStandard

----------------------------------------------------------------------------------------------------------

singleTop模式

If an instance of the activity already exists at the top of the current task, the system routes the intent to that instance through a call to its onNewIntent() method, rather than creating a new instance of the activity. The activity can be instantiated multiple times, each instance can belong to different tasks, and one task can have multiple instances (but only if the activity at the top of the back stack is not an existing instance of the activity).

For example, suppose a task's back stack consists of root activity A with activities B, C, and D on top (the stack is A-B-C-D; D is on top). An intent arrives for an activity of type D. If D has the default "standard"launch mode, a new instance of the class is launched and the stack becomes A-B-C-D-D. However, if D's launch mode is "singleTop", the existing instance of D receives the intent through onNewIntent(), because it's at the top of the stack—the stack remains A-B-C-D. However, if an intent arrives for an activity of type B, then a new instance of B is added to the stack, even if its launch mode is "singleTop".

Note: When a new instance of an activity is created, the user can press the Back button to return to the previous activity. But when an existing instance of an activity handles a new intent, the user cannot press the Back button to return to the state of the activity before the new intent arrived in onNewIntent().

比如ActivitySingleTop是设定为启动模式是singleTop的,

然后,当前的栈顶是有ActivitySingleTop类型的对象;然后,其它Activity要启动ActivitySingleTop,那么,此时,系统不会重新创建ActivitySingleTop对象,而是直接使用位于栈顶的ActivitySingleTop对象。

也就是说,如果要启动的Activity,它的启动模式是SingleTop,并且,当前栈顶已经有该Activity了,那么,系统就不会创建新的Activity,这一点与standard启动模式的效果不同。

例子:

<activity

android:name="com.testlaunchemode.activity.ActivitySingleTop"

android:launchMode="singleTop"

/>

代码:

public class ActivitySingleTop extends Activity {

private TextView tv ;

private MyApp myApp ;

public void onCreate(Bundle state) {

super.onCreate(state);

              setContentView(R.layout. singletop_activity);

              inital();

       }

private void inital() {

tv = (TextView) findViewById(R.id. tv);

myApp = (MyApp) getApplicationContext();

tv.setText( "SingleTop launchMode, times:" + myApp .inCreaseTimes());

       }

public boolean onTouchEvent(MotionEvent event) {

              Intent intent = new Intent(this , ActivitySingleTop.class);

              startActivity(intent);

return super .onTouchEvent(event);

       }

@Override

protected void onNewIntent(Intent intent) {

              setTitle( "I am Activity1 too, but I called onNewIntent!" );

super.onNewIntent(intent);

       }

}

效果:

首次进入:

此时在栈顶的是ActivitySingleTop类型的对象,即是当前Activity:

Image

然后,我触摸当前Activity多次,下面的的times依然保持0:

这说明,在启动ActivitySingleTop时,并没有创建新的ActivitySingleTop对象,而是使用当前位于栈顶的ActivitySingleTop对象。系统会将调用者发出的intent,作为参数,传递给位于栈顶的ActivitySingleTop对象的onNewIntent方法。

注意:如果被调用的Activity(使用singleTop启动模式)不是处于栈顶,那么,不具备上述效果。

Image(1)

然后,我按下返回键,就直接返回到其他Activity。

-----------------------------------------------------------------------------------------------------

singleTask模式

"singleTask"
The system creates a new task and instantiates the activity at the root of the new task. However, if an instance of the activity already exists in a separate task, the system routes the intent to the existing instance through a call to its onNewIntent() method, rather than creating a new instance. Only one instance of the activity can exist at a time.

Note: Although the activity starts in a new task, the Back button still returns the user to the previous activity.

As another example, the Android Browser application declares that the web browser activity should always open in its own task—by specifying the singleTask launch mode in the <activity> element. This means that if your application issues an intent to open the Android Browser, its activity is not placed in the same task as your application. Instead, either a new task starts for the Browser or, if the Browser already has a task running in the background, that task is brought forward to handle the new intent.

Regardless of whether an activity starts in a new task or in the same task as the activity that started it, the Back button always takes the user to the previous activity. However, if you start an activity that specifies the singleTask launch mode, then if an instance of that activity exists in a background task, that whole task is brought to the foreground. At this point, the back stack now includes all activities from the task brought forward, at the top of the stack. Figure 4 illustrates this type of scenario.

Image(2)

Figure 4. A representation of how an activity with launch mode "singleTask" is added to the back stack. If the activity is already a part of a background task with its own back stack, then the entire back stack also comes forward, on top of the current task.

被启动的Activity,如果它的启动模式是singleTask,那么:

1.如果在某个task中,包含该Activity,那么,会将intent传递到该Activity的onNewIntent()方法。

2.如果,没有task是包含该Activity的,那么,系统就创建一个新的task,然后,新创建的Activity实例,作为新的task的根activity。

例子1:将被启动的Activity,已经存在于当前的task中。

首次启动ActivitySingleTask:

Image(3)

然后,启动另外一个Activity:

Image(4)

然后,再启动ActivitySingleTask:

3-1

由此可以知道,如果要启动的ActivitySingleTask已经在task中了,那么,系统会将Intent传递给该

task中的ActivitySingleTask实例,不会再次创建一个新的ActivitySingleTask实例。

所以,在当前task中,只有一个ActivitySingleTask实例。所以,启动模式SingleTask,如其名字,可以解释为,

在该Activity所在的task中,该Activity只存在一个实例。

例子2:在同一个应用中,在当前task中,并没有ActivitySingleTask实例存在的情况下

首先启动一个standard Activity:

Image(5)

然后,再启动一个在当前task中并不存在的singleTask Activity:

Image(6)

通过taskId可以判断出,这两个Activity是位于同一个task的。事实上,在同一个应用下,当前task如果没有ActivitySingleTask2类型的实例时,系统并不会创建一个新的task来存放ActivitySingleTask2实例。系统只是将创建好的ActivitySingleTask2实例,存放在当前task中。

【The system creates a new task and instantiates the activity at the root of the new task】

文档中的这句话,如果一个启动模式是SingleTask的Activity与启动者是在同一个应用下,那么,就不成立。

例子3,将要被启动的SingleTaskActivity,与启动者是在不同的应用中

首先,创建一个app,其中包含将要被启动的SingleTaskActivity:

Image(7)

然后,在另外一个app中,启动OneApp中的Cactivity:

Image(8)

然后,调用的结果就是:

Image(9)

然后,不断的返回,会返回到Bactivity,Aactivity,这两个Activity都和Cactivity处于同一个task中。

从上述结果可以知道,如果被启动的Activity,它的启动模式是SingleTask,并且它在其它应用中,那么,

被启动Activity和启动Activity是属于不同的task的;此外,如果SingleTask Activity所在的task,是background状态的,那么,会将整个task变为forward 状态。

如下图所示:

Image(10)

---------------------------------------------------------------------------------------------------------------------------------------------

singleInstance模式

Same as "singleTask", except that the system doesn't launch any other activities into the task holding the instance. The activity is always the single and only member of its task; any activities started by this one open in a separate task.

如果某个Activity,假设是singleInstanceActivity,设定为singleInstance模式,那么,当singleInstanceActivity被启动后,系统会创建一个新的task,专门只用来存放singleInstanceActivity实例。

并且,当singleInstanceActivity启动其它Activity时,其它Activity实例,是放在一个新的task中,不会与singleInstanceActivity存放在同一个task中。也就是说,一个task中,只有singleInstanceActivity一个实例。

例子:

首先,启动该该singleInstanceActivity:

Image

然后,启动另外一个Activity:

Image

然后,再启动singleInstanceActivity:

Image

由上可知,singleInstance是独占一个task的;然后,如果系统已经存在一个task,该task已经包含ActivitySingleInstance实例,那么,系统,会将启动ActivitySingleInstance的Intent传递给该实例,这时,调用的就是该实例的onNewIntent方法,不会再创建一个新的ActivitySingleInstance实例。

------------------------------------------------------------------------------------------

原文地址:https://www.cnblogs.com/ttylinux/p/4067936.html