Android Startup Mode Task

Keywords: Android Attribute

Android Startup Mode Task

This article was written because in an interview the other day, the interviewer said that the Single Instance model would create a new haze, but Single Task would not. First of all, don't say that this is right or wrong (if you have to say right or wrong, that's wrong), because the sentence is ambiguous. Ham? Just return haze? Task haze? Have you considered the taskAffinity attribute? So it's wrong to say that in a general way. First, this article is wrong. In order to record, the second is to clarify the task (Task) & haze (return haze, task haze).

concept

(stack)

The basic features of stacks are:

  • First in, then out.

  • In addition to the head and tail nodes, each element has a precursor and a successor.

task

Tasks refer to a series of activities that interact with users while performing a specific job. These activities are arranged on the stack (i.e. the return stack) in their respective open order.

Return to
In official documents, the concept of return haze can not be found, but according to the context in which the official document is described, it can be understood as a sequence queue responding to the Android return key. This is a description standing on the user's intuitive feeling. The description unit in Android is only Task.

Mission task
There is no such concept in official documents. For ease of understanding, I refer to a series of activities queued in the order of the rules as task stacks.

Personal understanding

Because the official document does not specify what is the return hairpin, in actual development, if the stack is the basic unit of measurement, it is easy to be bypassed by oneself. If the task is the basic unit of measurement, it is easy to understand the four Android start-up modes. I personally understand the return stack as follows: there is only one return hairpin (because there is only one return key), and the return hairpin. The basic element of operation is task. The return key operation is to return to the task in the foreground. Each task maintains a stack of activities to respond to the return key.

Activity's Four Startup Patterns

  • "standard" (default mode)
    Default. The system creates new instances of Activity in the task of starting Activity and transmits Intent to them. Activity can be instantiated many times, and each instance can belong to a different task, and a task can have multiple instances.

  • "singleTop"
    If an instance of Activity already exists at the top of the current task, the system will transfer Intent to it by calling the onNewIntent() method of the instance instead of creating a new instance of Activity. Activity can be instantiated many times, and each instance can belong to a different task, and a task can have multiple instances (provided that activity at the top of the return stack is not an existing instance of activity).

For example, suppose that the task's return stack contains root Activity A, Activity B, C, and D at the top (the stack is A-B-C-D; D is at the top). Receive Intent for Class D Activity. If D has the default "standard" startup mode, new instances of this class will be started, and the stack will become A-B-C-D-D. However, if the startup mode of D is "singleTop", the existing instance of D receives Intent through onNewIntent(), because it is at the top of the stack; and the stack is still A-B-C-D. However, if an Intent for Class B Activity is received, a new instance of B is added to the stack, even if its startup mode is "singleTop".

Note: When creating a new instance for an activity, the user can press the "Back" button to return to the previous activity. However, when an existing instance of Activity processes a new Intent, the user cannot press the "Return" button to return to the status of Activity before the new Intent reaches onNewIntent().

  • "singleTask"
    The system creates new tasks and instantiates Activity at the bottom of the new tasks. However, if an instance of the Activity already exists in a single task, the system will transfer Intent to the existing instance by calling its onNewIntent() method instead of creating a new instance. Only one instance of Activity can exist at a time.

Note: Although Activity is started in the new task, the user presses the "Back" button to return to the previous Activity.

  • "singleInstance".
    Like "singleTask", the system does not start any other Activity into the task containing the instance. This Activity is always the only member of its task; any Activity initiated by this Activity is opened in a separate task.

Let's look at another example where the Android browser application declares that Web browser Activity should always be open in its own task (by specifying singleTask startup mode in the < activity > element). This means that if your application sends out Intent that opens the Android browser, its Activity is in a different task from your application. Instead, the system will start a new task for the browser, or if the browser's existing task is running in the background, it will move the task up a layer to handle the new Intent.

Whether an Activity is started in a new task or in the same task as an Activity, the user always moves to the previous Activity by pressing the "Back" button. However, if you start an Activity that specifies the singleTask startup mode, when an instance of the Activity exists in a background task, the entire task will be transferred to the front end. At this point, the return stack includes all activities in the task that moves up to the top of the stack. The picture above shows this.

The figure above shows how to add Activeness with startup mode of "singleTask" to the return stack. If Activity is already part of a background task that has its own return stack, the entire return stack will move up to the top of the current task.

Reference resources: Official Documents from March 14, 2017 (Later changes may be made on the official website)

About the android:taskAffinity attribute

android:taskAffinity

Tasks that have affinity with Activity. Conceptually, activities with the same affinity belong to the same task (from the user's point of view, belong to the same "application"). The affinity of a task is determined by the affinity of its root activity.
Affinity determines two things - the parent task that Activity changes to (see allowTaskReparenting property) and the task that will be used to accommodate Activity when it is started through the FLAG_ACTIVITY_NEW_TASK flag.
By default, all activities in the application have the same affinity. You can set this property to combine them in different ways, or even put activities defined in different applications within the same task. To specify that Activity has no affinity with any task, set it to an empty string.
If this property is not set, Activity inherits the affinity set for the application (see taskAffinity attribute of the < Application > element). The name of the package that applies the default affinity is set by the < manifest > element.

Reference resources: Official Documents from March 14, 2017 (Later changes may be made on the official website)

Similarities and differences between testing Single Task and Single Instance

I wrote a Demo test.

When I configure Single TaskA:

<activity android:name=".SingleTaskA" android:launchMode="singleTask" android:taskAffinity="com.didikee.temp"/>

Start a standard BActivity in Single Task A:

public class SingleTaskA extends BaseLauncherModeActivity {
    @Override
    protected Class gotoActivity() {
        return StandardB.class;
    }

    @Override
    protected String setModeTextShow() {
        return Constant.SINGLE_TASK;
    }
}

In StandardB, I always start StandardB itself:

public class StandardB extends BaseLauncherModeActivity {
    @Override
    protected Class gotoActivity() {
        return StandardB.class;
    }

    @Override
    protected String setModeTextShow() {
        return Constant.STANDARD+"Repeat";
    }
}

Add the following basic categories:

public abstract class BaseLauncherModeActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_base_launcher_mode);
        String text = setModeTextShow();
        Button button = (Button) findViewById(R.id.bt);
        button.setText("Pattern: "+text);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Class aClass = gotoActivity();
                if (aClass==null)return;
                startActivity(new Intent(getApplicationContext(),aClass));
            }
        });
        int taskId = getTaskId();
        Log.d(Constant.TAG,"taskId: "+taskId);
    }

    protected abstract Class gotoActivity();

    protected abstract String setModeTextShow();
}

The following results are obtained:

03-14 10:32:32.287 22561-22561/com.didikee.androidlaunchermode D/AndroidLauncherMode: taskId: 26
03-14 10:32:37.691 22561-22561/com.didikee.androidlaunchermode D/AndroidLauncherMode: taskId: 26
03-14 10:32:42.120 22561-22561/com.didikee.androidlaunchermode D/AndroidLauncherMode: taskId: 27
03-14 10:32:45.961 22561-22561/com.didikee.androidlaunchermode D/AndroidLauncherMode: taskId: 27
03-14 10:32:52.105 22561-22561/com.didikee.androidlaunchermode D/AndroidLauncherMode: taskId: 27
03-14 10:32:53.531 22561-22561/com.didikee.androidlaunchermode D/AndroidLauncherMode: taskId: 27
03-14 10:32:55.748 22561-22561/com.didikee.androidlaunchermode D/AndroidLauncherMode: taskId: 27
03-14 10:32:56.763 22561-22561/com.didikee.androidlaunchermode D/AndroidLauncherMode: taskId: 27

As you can see, Single Task A starts a new task (Task) with an ID of 27, and then starts Standard B in Single Task A without doing anything else, adding it directly to the task just started by Single Task A.

Now I remove the definition of task Affinity attribute and get:

03-14 16:42:10.604 31062-31062/com.didikee.androidlaunchermode D/AndroidLauncherMode: taskId: 29
03-14 16:42:15.261 31062-31062/com.didikee.androidlaunchermode D/AndroidLauncherMode: taskId: 29
03-14 16:42:16.865 31062-31062/com.didikee.androidlaunchermode D/AndroidLauncherMode: taskId: 29
03-14 16:42:19.197 31062-31062/com.didikee.androidlaunchermode D/AndroidLauncherMode: taskId: 29
03-14 16:42:20.232 31062-31062/com.didikee.androidlaunchermode D/AndroidLauncherMode: taskId: 29
03-14 16:42:21.049 31062-31062/com.didikee.androidlaunchermode D/AndroidLauncherMode: taskId: 29
03-14 16:42:22.180 31062-31062/com.didikee.androidlaunchermode D/AndroidLauncherMode: taskId: 29

As you can see, new tasks are not created by default.

Now, change Single Task A to Single Instance A, and then start Standard B (with the code on it) with the following results:

03-14 16:46:59.669 2273-2273/com.didikee.androidlaunchermode D/AndroidLauncherMode: taskId: 30
03-14 16:47:09.367 2273-2273/com.didikee.androidlaunchermode D/AndroidLauncherMode: taskId: 30
03-14 16:47:10.602 2273-2273/com.didikee.androidlaunchermode D/AndroidLauncherMode: taskId: 31
03-14 16:47:12.013 2273-2273/com.didikee.androidlaunchermode D/AndroidLauncherMode: taskId: 30
03-14 16:47:14.438 2273-2273/com.didikee.androidlaunchermode D/AndroidLauncherMode: taskId: 30
03-14 16:47:15.429 2273-2273/com.didikee.androidlaunchermode D/AndroidLauncherMode: taskId: 30

As you can see, Single InstanceA has created a new task id of 31. Start StandardB in Single InstanceA or continue to add it to the previous task.

Conclusion:

  1. Android is task-centric, so don't get sidetracked by the stack.

  2. Single Instance is bound to create a new task with only one instance in it.

  3. SingleTask does not create new tasks by default, but it can create new tasks through task Affinity, which can add other elements.

Finally, the wrong welcome exchanges.

Posted by Cornelia on Thu, 18 Apr 2019 17:09:34 -0700