preface

The background of this article comes from Friday, when a friend of mine had a private conversation with me about a question. To be honest, I was “pretty shocked” :

  • 1, The question seems simple enough, about the Activity launch mode… But the details did touch on my intellectual blind spot.
  • 2, This friend has posted a detailed PDF document, which seems to summarize and praise this learning attitude frequently

Here on the basis of the analysis of the starting mode, or to answer his questions, or to verify his conjecture. You can also ask yourself if you can answer the following question:

Problem a:

Verification section: 2.3

Problem two:

This is a very interesting phenomenon, probably everyone has not noticed it

Question 3:

The answer here is an extension of the above question and will be explained in Section 2.1.

Problem four:

This question should also be many people feel “contrary to common sense”, in fact, the official document has answered this question. Solution 2.4

The body of the

1. Understand the concept

The concept of Task was somewhat unavoidable during the study of the Ativity. From the official documentation, we can basically understand the relationship between Task and Stack…

A classic picture:

Activities are grouped together in the concept of tasks, and whether they are multiple activities in a single Task or multiple tasks grouped together, they are contained in a Stack.

However, how many dumpsys activities have left you wondering: what is a TaskRecord?

1.1, Stack, Task, TaskRecord?

Task and TaskRecord are the same concept. TaskRecord is a class in the framework layer. It is the code implementation of the abstract concept Task. Let’s take a look at Dumpsys’s diagram:

Use the adb shell dumpsys activity command

Using the command: adb shell dumpsys activity activities | sed – En – e ‘/ Stack # / p – e’/Running activities /, / Run # 0 / p ‘

The two images are the same Activity stack scenario, but you can see that TaskRecord and Task are the same concept.

1.2, launchModel

Boot mode, which we’re all familiar with, comes right out of the mouth:

  • standard
  • singleTop
  • singleTask
  • singleInstance

I won’t elaborate on their concepts here, because there’s no point in copying and pasting. (More on the four modes and taskAffinity and various Flags later.) But here’s an official chart to get a feel for it:

This is representative of Google’s attitude towards singleTask and singleInstance, which means that these modes are not designed for mainstream activities and therefore require a true understanding of them before using them.

2. Understand thoroughly from the demo

The demo is very simple and defines five activities:

<activity
    android:name=".test.TestMainLauncherActivity"
    android:screenOrientation="portrait">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

<activity android:name=".test.TestSingleInstanceLauncherActivity"
    android:launchMode="singleInstance"/>
<activity android:name=".test.TestTopAffinityLauncherActivity"
    android:launchMode="singleTop"
    android:taskAffinity="app.mdove"/>
<activity android:name=".test.TestSingleTaskLauncherActivity"
    android:launchMode="singleTask"
    />
<activity android:name=".test.TestSingleTaskAffinityLauncherActivity"
        android:taskAffinity="app.mdove.singletask"
        android:theme="@style/MyAppTheme"
        android:launchMode="singleTask"
        />
Copy the code

2.1. Understand taskAffinity

First, let’s take a look at the documentation for Android :taskAffinity:

A task that is similar to an Activity. Conceptually, activities that have the same similarity belong to the same task (or, from the user’s perspective, to the same “application”). The similarity of a task is determined by the similarity of its root Activity.

Similarity determines two things:

  • Activity Changes the task after the parent item (seeallowTaskReparentingProperty, this property is more interesting, but let’s press not table)
  • And the tasks that hold the Activity when it is started with the FLAG_ACTIVITY_NEW_TASK flag.

From the description of the document alone, it seems a little misty. So let’s use the actual code to verify what taskAffinity means.

Here I first post the conclusion:

TaskAffinity does not make sense in Standard or singleTop. The effect of taskAffinity depends on FLAG_ACTIVITY_NEW_TASK being used when the Activity is started. (also mentioned on the website above)

2. After the taskAffinity mode is successfully started, the new Activity will reside in the new Task. And the activities that are started by this Task (without taskAffinity) are all in this Task.

Next, let’s verify this conclusion (operation route) :

  • Start TestMainLauncherActivity TestTopAffinityLauncherActivity

  • And then start on TestTopAffinityLauncherActivity TestMainLauncherActivity

  • TestTopAffinityLauncherActivity by FLAG_ACTIVITY_NEW_TASK labels on TestMainLauncherActivity, started

  • Finally by TestMainLauncherActivity TestTopAffinityLauncherActivity started

Can you construct the structure of a Task in your head? Here’s dumpsys’s picture:

A quick explanation:

1, look at the Task # 21, because we don’t have increased FLAG_ACTIVITY_NEW_TASK TestTaskAffinityLauncherActivity starts, so its Task and no change.

2, in the Task # 22, TestTaskAffinityLauncherActivity through FLAG_ACTIVITY_NEW_TASK directly enters the new Task, and subsequent start Activity and its “coexist one room.

Let’s look at a very interesting phenomenon (answer question 2)

If we started an Activity1 with FLAG_ACTIVITY_NEW_TASK + taskAffinity and started a normal Activity2 with that Activity1, if we started Activity1 on Activity2, You will find no reaction!!

The task where Activity1 is located has been moved to the foreground. I haven’t noticed this detail for a long time. If it hadn’t been for this little friend’s reminding, I might not have noticed this problem for a long time.

When this happened again, I was stunned. My first thought was to look through the documentation. Is there a hint in the documentation? And then, to my great disappointment, I didn’t find any answer to this phenomenon.

Since there is no explanation in the documentation, let’s look at the source code… But I just clicked on FLAG_ACTIVITY_NEW_TASK and saw a big comment that said:

If the Task runs the Activity you want to satrt, it will not start a new Activity, but move the Task to the foreground. This comment is exactly the phenomenon we encountered…

In the case of FLAG_ACTIVITY_NEW_TASK, it essentially looks for the Task declared by the taskAffinity to start. If it doesn’t, it behaves just like a normal Activity, so it doesn’t do anything special.

Which begs the question: Why? Honestly, I don’t know… I guess to provide such a capability, after all, the IMAGINATION of PM is unlimited. (If we want to display the Activity to start in this case, don’t forget FLAG_ACTIVITY_CLEAR_TOP.)

2.2. Understand singleTask

Under singleTask, only when taskAffinity is set will a new Task be created for the Activity that is started. And subsequent activities enter the Task as well.

I’m sure you’re all familiar with this…

2.3. Understand singleInstance

SingleInstance should be pretty clear to you. Because it’s special: always have a Task to yourself.

Here we look at two interesting features:

Activities started with singleInstance are FLAG_ACTIVITY_NEW_TASK by default. So if you start singleTop with taskAffinity through singleInstance, new tasks will start.

Here’s one detail: FLAG_ACTIVITY_NEW_TASK only, no taskAffinity. It will put the started Activity in the root stack. So here’s a detail:

If an Activity is started by singleInstance, the root Task is pulled to the foreground because it is added to the root stack, and the back key displays the Activity below the root Task, as follows:

When the back off TestMainLaunncherAcctivity, display is still TestMainLaunncherAcctivity. Because they’re on the same stack as #43.

FLAG_ACTIVITY_NEW_TASK + FLAG_ACTIVITY_CLEAR_TOP = singleTask?

FLAG_ACTIVITY_NEW_TASK + FLAG_ACTIVITY_CLEAR_TOP = singleTask.

But that’s not entirely true, it’s not from me, it’s from the document:

Note the red line: using these flags does not trigger onNewIntent() for standard mode, but destroys and rebuilds.

The end of the

OK, that’s the end of this article… However, we can also see from Google’s attitude that “singleTask” and “singleInstance” are reminders for careful use.

It seems that Standard and singleTop have met our needs… However, it seems that the four boot modes are really underrated…

I am a fresh graduate, recently and friends maintain a public account, the content is that we in the transition from fresh graduate to the development of this way stepped on the pit, as well as our step by step learning records, if interested in friends can pay attention to it, together with fuel ~