Android Activity Launch Mode SingleTask SingleInstance Example

The previous article Android Activity Launch Mode Standard SingleTop Example has introduced the two android activity launch modes Standard and SingleTop. This article will introduce the other two android activity launch modes SingleTask and SingleInstance which are more difficult to understand.

1. Activity Launch Mode SingleTask.

If you can not watch the above video, you can see it on the youtube URL https://youtu.be/_ReQFBVQPCY

  1. When you request an instance of activity that configured with the singleTask launch mode, if one instance has existed in the current back stack, then that instance will be pop up to the top of the back stack and all other activity instances above it will be removed from the back stack.
    android-activity-launch-mode-singletask
  2. The below example has three activities, ActivityLaunchModeFirstActivity, ActivityLaunchModeSecondActivity, ActivityLaunchModeThirdActivity.
  3. Only the second activity is configured in 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>
  4. When clicking the button to start or restart another activity, the code will print out all the activities that exist in the current task back stack, below are the example source files.
  5. 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>
  6. 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);
        }
    }
  7. 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>
  8. 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);
        }
    }
  9. 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>
  10. 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);
        }
    }
  11. ActivityManagerUtil.java. This class is the util class that provides a method to print out all activities info in the 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;
    
    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.

If you can not watch the above video, you can see it on the youtube URL https://youtu.be/6v0t4OE1j2s

  1. This launch mode will make the activity saved in a new task back stack. And the back stack contains only one activity, it is like a global activity.
  2. 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>
  3. Run the above example code again, you will get the 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.
    Task Id : 516
    Activity Number : 1
    Base Activity : ComponentInfo{com.dev2qa.example/com.dev2qa.example.ActivityLaunchModeFirstActivity}
    Top Rctivity : ComponentInf0{com.dev2qa.example/com.dev2qa.example.ActivityLaunchModeFirstActivity}
    ********************************************************
    Task Id: 517
    Activity Number: 1
    Base Activity : ComponentInfo{com.dev2qa.example/com.dev2qa.example.ActivityLaunchModeSecondActivity}
    Top Rctivity : ComponentInfo{com.dev2qa.example/com.dev2qa.example.ActivityLaunchModeSecondActivity}
    ********************************************************
    
    Task Id: 516
    Activity Number: 2
    Base Activity : ComponentInfo{com.dev2qa.example/com.dev2qa.example.ActivityLaunchModeFirstActivity} 
    Top Rctivity : ComponentInfo{com.dev2qa.example/com.dev2qa.example.ActivityLaunchModeThirdActivity} 
    ********************************************************
     
    Task Id: 517
    Activity Number: 1
    Base Activity : ComponentInfo{com.dev2qa.example/com.dev2qa.example.ActivityLaunchModeSecondActivity} 
    Top Rctivity : ComponentInfo{com.dev2qa.example/com.dev2qa.example.ActivityLaunchModeSecondActivity} 
    ********************************************************
    
    Task Id: 516
    Activity Number: 3
    Base Activity : ComponentInfo{com.dev2qa.example/com.dev2qa.example.ActivityLaunchModeFirstActivity} 
    Top Rctivity : ComponentInfo{com.dev2qa.example/com.dev2qa.example.ActivityLaunchModeThirdActivity} 
    ********************************************************
    

Leave a Comment

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.