I do not know whether you have encountered the following situation when using APP at ordinary times:

This came up when I was using Zhihu recently. You can see that zhihu is not in the task list, but it is clearly still working. It is normal that you open Zhihu now to see the large probability, the reason will be mentioned later.

The most straightforward way to kill an APP process is to cross it off the task list. So, Survivhack added a new idea: If you hide the app from the task list, you can’t kill it.

To be clear, this article is not intended to teach you how to save, but to explore how to do it and to talk about multitasking on Android. And I was genuinely disgusted by the experience.

How to kill it?

Task lists aren’t the only way to kill an APP. Let’s look at how to kill an APP first.

adb

Adb shell ps: adb shell ps: adb shell ps: adb shell ps: adb shell ps

You can then use ADB shell am force-stop com.zhihu. Android to force kill the Zhihu process.

System Settings

For the average user, there is a solution. Enter system Settings, find Zhihu in application Settings, and click Forcibly stop:

But no matter which method, it is more troublesome, sincerely hope that we do not do so.

excludeFromRecents

In fact, Android is allow us to hide in the task list, and is very simple, as long as the statement in listing the Android: excludeFromRecents = “true”.

Let’s try a new project and add this configuration to MainActivity:

<activity
    android:name=".MainActivity"
    android:excludeFromRecents="true">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
Copy the code

This way you can achieve the effect of not showing on the task list.

But this alone does not achieve the effect of Zhihu, because it is shown in the task list when opened for the first time. Let’s introduce another concept of multitasking.

taskAffinity

The task list is called because it shows the tasks that are currently executing, not the applications that are currently running. By default, there is only one task for each application.

Each task has a TaskAffinity, which can be thought of as the task name, which by default is the package name of the application. We can use the taskAffinity attribute to assign different task names to activities, allowing an APP to have multiple tasks.

Both excludeFromRecents and taskAffinity work only on the root Activity in the stack, but they actually work on the Task stack, not the Activity.

For example, we add a SecondActivity with the following listing configuration:

<activity
    android:name=".MainActivity"
    android:label="Task 1"
    android:taskAffinity="com.nanbox.task1">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

<activity
    android:name=".SecondActivity"
    android:label="Task 2"
    android:launchMode="singleTask"
    android:taskAffinity="com.nanbox.task2" />
Copy the code

When both activities are started, two tasks appear in the task list.

TaskAffinity is often used in conjunction with singleTask. When launching a singleTask Activity, the system compares the current taskAffinity with the new taskAffinity. If not, the Activity is started in a new Task.

In addition, not only an application can have multiple tasks, different applications can also belong to the same task, the task can be cross-process. This kind of usage scenario should be relatively few and will not be covered here.

SAO operation

Based on the above multi-tasking, if an application has two tasks, one visible and one invisible, the user can only kill the visible task in the task list, and the invisible task can continue to run, wouldn’t that be able to survive to a certain extent?

Let’s try the same code as above, but this time make Task 2 invisible in the Task list:

<activity
    android:name=".MainActivity"
    android:label="Task 1"
    android:taskAffinity="com.nanbox.task1">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

<activity
    android:name=".SecondActivity"
    android:excludeFromRecents="true"
    android:label="Task 2"
    android:launchMode="singleTask"
    android:taskAffinity="com.nanbox.task2" />
Copy the code

If the SecondActivity already exists, start it directly to restore the status of the last application:

Activity activity = ActivityProvider.getActivity();
if(activity ! =null) {
    Intent intent = new Intent(this, activity.getClass());
    startActivity(intent);
    finishAndRemoveTask();
}
Copy the code

So you have this effect:

GIF repeated playback is not very good reflect the effect, interested in your own run to see.

When you start Task1 for the first time, you see it in the task list. When you start Task2 and end Task1, the task list becomes empty, but clicking on the desktop app restores Task2 to running.

This is also why it is normal for Zhihu to start up for the first time.

The resources

Recents Screen

Activity List Configuration