首页 > 代码库 > Android中launchMode模式详解

Android中launchMode模式详解

关于Android中launchMode的文章介绍的真心不少,广为流传而且介绍的最详细的莫过于这篇文章http://blog.csdn.net/android_tutor/article/details/6310015。但是这篇文章中关于singletask和singleinstance在评论中还是有些不解和争论,在此根据实例重点说下这两种模式:

实例简介:有两个Activity,分别为AActivity和BActivity,界面相同。点击按钮A和B,分别启动AActivity和BActivity,观察效果:


上代码:

layout_task.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/buttonStartA"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="StartA" >
    </Button>

    <Button
        android:id="@+id/buttonStartB"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="StartB" >
    </Button>

</LinearLayout>

AActivity.java

package com.example.activitytask;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class AActivity extends Activity{
	
	private static final String TMG = "ActivityTask";
	private static int mIndex = 0;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.layout_task)  ;
		mIndex++  ;
		Log.i(TMG,"AActivity Create"+mIndex+"  TaskId="+getTaskId())  ;
		Button _buttonStartA = (Button)findViewById(R.id.buttonStartA)  ;
		_buttonStartA.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				Intent _intent = new Intent(AActivity.this,AActivity.class)  ;
				startActivity(_intent) ;
			}
		}) ;
		
		
		Button _buttonStartB = (Button)findViewById(R.id.buttonStartB)  ;
		_buttonStartB.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				Intent _intent = new Intent(AActivity.this,BActivity.class)  ;
				startActivity(_intent) ;
			}
		}) ;
	}
	@Override
	protected void onDestroy() {
		super.onDestroy();
		Log.i(TMG,"AActivity Destory"+mIndex+"  TaskId="+getTaskId())  ;
		mIndex--;
	}
	
	@Override
	protected void onNewIntent(Intent intent) {
		super.onNewIntent(intent);
		Log.i(TMG,"AActivity onNewIntent"+mIndex+"  TaskId="+getTaskId())  ;
	}

}

BActivity.java

package com.example.activitytask;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class BActivity extends Activity{

	private static final String TMG = "ActivityTask";
	private static int mIndex = 0 ;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.layout_task)  ;
		mIndex++  ;
		Log.i(TMG,"BActivity Create"+mIndex+"  TaskId="+getTaskId())  ;
		Button _buttonStartA = (Button)findViewById(R.id.buttonStartA)  ;
		_buttonStartA.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				Intent _intent = new Intent(BActivity.this,AActivity.class)  ;
				startActivity(_intent) ;
			}
		}) ;
		
		
		Button _buttonStartB = (Button)findViewById(R.id.buttonStartB)  ;
		_buttonStartB.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				Intent _intent = new Intent(BActivity.this,BActivity.class)  ;
				startActivity(_intent) ;
				
			}
		}) ;
	}
	@Override
	protected void onDestroy() {
		super.onDestroy();
		Log.i(TMG,"BActivity Destory"+mIndex+"  TaskId="+getTaskId())  ;
		mIndex--;
	}
	
	@Override
	protected void onNewIntent(Intent intent) {
		super.onNewIntent(intent);
		Log.i(TMG,"BActivity onNewIntent"+mIndex+"  TaskId="+getTaskId())  ;
	}

}

1.设置两个Activity的android:launchMode="singleTask"

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.activitytask"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="18" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.activitytask.AActivity"
            android:label="AActivity"
            android:launchMode="singleTask" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.example.activitytask.BActivity"
            android:label="BActivity"
            android:launchMode="singleTask" />
    </application>

</manifest>

程序刚启动时的打印结果

点击startB按钮打印效果

进入BActivity界面后,这时再点击startA按钮打印结果(先清屏)



这时我们发现BActivity销毁,此时再点击startB,BActivity重新创建


总结:当一个Activity被设置为singletask时

(1)它并没有创建新的任务栈(根据上面打印效果展示,AActivity和BActivity的TaskId都等于76)

(2)如果它已经存在于栈中,再次请求触发此Activity时,会调用此类实例的onNewIntent方法,不会重新创建新的实例

(3)如果此类所在的任务栈上面有其它Activity,那么其它的Activity会被销毁


2.设置两个Activity的android:launchMode="singleInstance"

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.activitytask"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="18" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.activitytask.AActivity"
            android:label="AActivity"
            android:launchMode="singleInstance" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.example.activitytask.BActivity"
            android:label="BActivity"
            android:launchMode="singleInstance" />
    </application>

</manifest>

程序刚启动时的打印结果


点击startB按钮打印效果


进入BActivity界面后,这时再点击startA按钮打印结果(先清屏)


再点击startB按钮打印结果(先清屏)


总结:当一个Activity被设置为singleinstance时

(1)如果此Activity没有实例,它会创建一个新的任务栈。(TaskId一个81,一个82)

(2)如果任务栈中已经有此实例,会调用onNewIntent方法,不会创建新的任务栈和实例

(3)独立成Taskstack ,并且有且仅有你自己 ,孤家寡人 。而且始终保持一个实例离栈的时候 , 先退当前的task ,再退另外的task