Android Activity Launch Mode SingleTask SingleInstance Example

Previous article Android Activity Launch Mode Standard SingleTop Example has introduced the two android activity launch mode standard and singleTop. This article will introduce the other two android activity launch mode singleTask and singleInstance which are more difficult to understand.

1. Activity Launch Mode SingleTask.

When you request an instance of activity that configured with singleTask launch mode, if one instance has exist in current back stack, then that instance will be pop up to the top of the back stack and all other activity instance above it will be removed from the back stack.

android activity launch mode singletask

Below example has three activity.

  1. ActivityLaunchModeFirstActivity.
  2. ActivityLaunchModeSecondActivity
  3. ActivityLaunchModeThirdActivity

Only the second activity is configured singleTask launch mode in AndroidManifest.xml file.

<activity android:name=".ActivityLaunchModeFirstActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

<activity
    android:name=".ActivityLaunchModeSecondActivity"
    android:launchMode="singleTask" />

<activity android:name=".ActivityLaunchModeThirdActivity"></activity>

When click the button to start or restart another acvivity, the code will print out all the activities exist in current task back stack.

android activity singletask launch mode example

activity_launch_mode_first.xml

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@+id/firstActivityIdTextView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="20dp"/>


    <Button
        android:id="@+id/startSecondActivityButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Start Second Activity"/>


</LinearLayout>

ActivityLaunchModeFirstActivity.java

package com.dev2qa.example;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.dev2qa.example.util.ActivityManagerUtil;

public class ActivityLaunchModeFirstActivity extends AppCompatActivity {

    private static final String TAG = "ACTIVITY_ID";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_launch_mode_first);

        ActivityManagerUtil.printCurrentTaskActivityList(getApplicationContext(), TAG);

        // Create Task and activity related id info.
        StringBuffer strBuf = new StringBuffer();
        strBuf.append("Task Id : ");
        strBuf.append(this.getTaskId());
        strBuf.append(" , Activity Id : ");
        strBuf.append(this.toString());

        // Set above info in TextView object.
        TextView firstActivityIdTextView = (TextView)findViewById(R.id.firstActivityIdTextView);
        firstActivityIdTextView.setText(strBuf.toString());

        // Log above info in logcat console.
        Log.d(TAG, strBuf.toString());

        // When click this button, start a new instance of second activity.
        Button startSecondActivityButton = (Button)findViewById(R.id.startSecondActivityButton);
        startSecondActivityButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(ActivityLaunchModeFirstActivity.this, ActivityLaunchModeSecondActivity.class);
                startActivity(intent);
            }
        });
    }

    // When activity restart, print activity info in back stack again.
    @Override
    protected void onRestart() {
        super.onRestart();
        ActivityManagerUtil.printCurrentTaskActivityList(getApplicationContext(), TAG);
    }
}

activity_launch_mode_second.xml

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@+id/secondActivityIdTextView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="20dp"/>

    <Button
        android:id="@+id/startThirdActivityFromSecondActivityButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Start Third Activity"/>

</LinearLayout>

ActivityLaunchModeSecondActivity.java

package com.dev2qa.example;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.dev2qa.example.util.ActivityManagerUtil;

public class ActivityLaunchModeSecondActivity extends AppCompatActivity {

    private static final String TAG = "ACTIVITY_ID";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_launch_mode_second);

        ActivityManagerUtil.printCurrentTaskActivityList(getApplicationContext(), TAG);

        // Create Task and activity related id info.
        StringBuffer strBuf = new StringBuffer();
        strBuf.append("Task Id : ");
        strBuf.append(this.getTaskId());
        strBuf.append(" , Activity Id : ");
        strBuf.append(this.toString());

        // Set above info in TextView object.
        TextView secondActivityIdTextView = (TextView)findViewById(R.id.secondActivityIdTextView);
        secondActivityIdTextView.setText(strBuf.toString());

        // Log above info in logcat console.
        Log.d(TAG, strBuf.toString());

        // When click this button, start a new instance of First activity.
        Button startThirdActivityFromSecondActivityButton = (Button)findViewById(R.id.startThirdActivityFromSecondActivityButton);
        startThirdActivityFromSecondActivityButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(ActivityLaunchModeSecondActivity.this, ActivityLaunchModeThirdActivity.class);
                startActivity(intent);
            }
        });
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        ActivityManagerUtil.printCurrentTaskActivityList(getApplicationContext(), TAG);
    }
}

activity_launch_mode_third.xml

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@+id/thirdActivityIdTextView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="20dp"/>

    <Button
        android:id="@+id/startSecondActivityFromThirdActivityButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Start Second Activity"/>

</LinearLayout>

ActivityLaunchModeThirdActivity.java

package com.dev2qa.example;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.dev2qa.example.util.ActivityManagerUtil;

public class ActivityLaunchModeThirdActivity extends AppCompatActivity {
    private static final String TAG = "ACTIVITY_ID";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_launch_mode_third);

        ActivityManagerUtil.printCurrentTaskActivityList(getApplicationContext(), TAG);

        // Create Task and activity related id info.
        StringBuffer strBuf = new StringBuffer();
        strBuf.append("Task Id : ");
        strBuf.append(this.getTaskId());
        strBuf.append(" , Activity Id : ");
        strBuf.append(this.toString());

        // Set above info in TextView object.
        TextView thirdActivityIdTextView = (TextView)findViewById(R.id.thirdActivityIdTextView);
        thirdActivityIdTextView.setText(strBuf.toString());

        // Log above info in logcat console.
        Log.d(TAG, strBuf.toString());

        // When click this button, start a new instance of second activity.
        Button startSecondActivityFromThirdActivityButton = (Button)findViewById(R.id.startSecondActivityFromThirdActivityButton);
        startSecondActivityFromThirdActivityButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(ActivityLaunchModeThirdActivity.this, ActivityLaunchModeSecondActivity.class);
                startActivity(intent);
            }
        });
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        ActivityManagerUtil.printCurrentTaskActivityList(getApplicationContext(), TAG);
    }
}

ActivityManagerUtil.java

This is the util class that provide method to print out all activities info in current task.

package com.dev2qa.example.util;

import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.util.Log;

import java.util.List;

/**
 * Created by Jerry on 12/11/2017.
 */

public class ActivityManagerUtil {

    public static void printCurrentTaskActivityList(Context context, String tagName)
    {
        ActivityManager activityManager = (ActivityManager) context.getSystemService( context.ACTIVITY_SERVICE );

        List<ActivityManager.AppTask> appTaskList = activityManager.getAppTasks();

        if(appTaskList!=null)
        {
            int size = appTaskList.size();
            for(int i=0;i<size;i++)
            {
                ActivityManager.AppTask appTask = appTaskList.get(i);
                ActivityManager.RecentTaskInfo recentTaskInfo = appTask.getTaskInfo();

                int taskId = recentTaskInfo.persistentId;

                int activityNumber = recentTaskInfo.numActivities;

                ComponentName origActivity = recentTaskInfo.origActivity;

                ComponentName baseActivity = recentTaskInfo.baseActivity;

                ComponentName topActivity = recentTaskInfo.topActivity;

                Log.d(tagName, "Task Id : " + taskId);
                Log.d(tagName, "Activity Number : " + activityNumber);

                if(origActivity!=null) {
                    Log.d(tagName, "Original Activity : " + origActivity.toString());
                }

                if(baseActivity!=null) {
                    Log.d(tagName, "Base Activity : " + baseActivity.toString());
                }

                if(topActivity!=null) {
                    Log.d(tagName, "Top Activity : " + topActivity.toString());
                }

                Log.d(tagName, "************************************************");
            }
        }
    }
}

2. Activity Launch Mode SingleInstance.

This launch mode will make the activity saved in a new task back stack. And the back stack contains only the one activity, it is like a global activity.

READ :   Android Activity Example - Switch Between Screens

Change AndroidManifest.xml to below.

<activity android:name=".ActivityLaunchModeFirstActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

<activity
    android:name=".ActivityLaunchModeSecondActivity"
    android:launchMode="singleInstance" />

<activity android:name=".ActivityLaunchModeThirdActivity"></activity>

Run above example code again, you will get below result. You can see the task id for the second activity has been changed. But the first and the third activity still exist in the same task back stack.

android activity singleinstance launch mode example

android activity launch mode singleinstance

(Visited 373 times, 2 visits today)

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.