Android 7 一键清理近期任务并保留白名单实现记录
2025-11-23 / 龙之叶   

需求背景

根据客户需求,需要提供一个一键结束所有应用并排除白名单的功能,效果类似 Android SystemUI 里「近期任务」界面的清理/结束任务按钮:
点击后清空近期任务,但对于指定的白名单应用,需要继续保持运行,不被杀掉。

在网上搜索后,并没有找到现成可用的实现方案,只能基于源码自行实现。

实现原理

既然 SystemUI 自身已经有「清理近期任务」的功能,就说明系统内部一定已经提供了相关接口,只是没有对外暴露。
通过调试 frameworks/base/packages/SystemUI 源码,可以看到:当按下近期任务按钮、执行清理操作时,会调用:

  • SystemServicesProxy#getRecentTasks(...):获取近期任务列表
  • 最终通过 ActivityManager.removeTask(int taskId) 来真正清理任务

思路就很明确了:

  1. 复用 SystemServicesProxy#getRecentTasks(...) 拿到当前所有近期任务列表;
  2. 根据白名单列表,将需要保留的应用从任务列表中移除;
  3. 对剩余任务逐个调用 ActivityManager.removeTask(...),完成清理。

为方便在系统中统一调用,这里通过自定义广播的方式来触发清理逻辑。


新增广播 KillProcessesReceiver

frameworks/base/packages/SystemUI/src/com/android/systemui/receiver/ 下新增文件:

  • KillProcessesReceiver.java

示例代码如下(去掉了多余的高亮标签,保留核心逻辑):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package com.android.systemui.receiver;

import android.app.ActivityManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.UserHandle;
import android.util.ArraySet;
import android.util.Log;

import com.android.systemui.recents.Recents;
import com.android.systemui.recents.misc.SystemServicesProxy;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
* 结束指定进程(清理近期任务,支持白名单)
*/
public class KillProcessesReceiver extends BroadcastReceiver {

public static final String ACTION = "con.yt.kill.processes";
private static final String TAG = "recent";

@Override
public void onReceive(Context context, Intent intent) {
if (!ACTION.equals(intent.getAction())) {
return;
}

PackageManager pm = context.getPackageManager();
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);

try {
SystemServicesProxy ssp = Recents.getSystemServices();
int currentUserId = UserHandle.USER_CURRENT;

// 获取近期任务列表
List<ActivityManager.RecentTaskInfo> tasks =
ssp.getRecentTasks(
ActivityManager.getMaxRecentTasksStatic(),
currentUserId,
false,
new ArraySet<>()
);

if (tasks == null || tasks.size() == 0) {
Log.e(TAG, "tasks Empty");
return;
}

// 读取白名单(包名或类名)
ArrayList<String> whiteApp =
intent.getStringArrayListExtra("whiteApp"); // 过滤白名单

if (whiteApp != null && !whiteApp.isEmpty()) {
Iterator<ActivityManager.RecentTaskInfo> iter = tasks.iterator();
while (iter.hasNext()) {
ActivityManager.RecentTaskInfo t = iter.next();
for (String s : whiteApp) {
if (s.equals(t.realActivity.getClassName())
|| s.equals(t.realActivity.getPackageName())) {
iter.remove();
Log.i(TAG, "package is in white list, id=" + t.id
+ ", package=" + s);
break;
}
}
}
}

if (tasks.size() == 0) {
Log.e(TAG, "tasks Empty");
return;
}

// 逐个清理剩余任务
Iterator<ActivityManager.RecentTaskInfo> iter = tasks.iterator();
while (iter.hasNext()) {
ActivityManager.RecentTaskInfo t = iter.next();
Log.i(TAG, "RecentTaskInfo stackId: " + t.stackId
+ ", baseActivity: " + t.baseActivity);

// 注意:这里使用 persistentId
am.removeTask(t.persistentId);
}
} catch (Exception e) {
Log.e(TAG, "Failed to get recent tasks", e);
}
}
}

核心逻辑说明:

  • 通过 Recents.getSystemServices() 拿到 SystemServicesProxy
  • 调用 getRecentTasks(...) 获取当前用户的所有近期任务;
  • 从 Intent 中取出白名单列表 whiteApp,按包名 / 类名过滤;
  • 对过滤后的任务使用 ActivityManager#removeTask(persistentId) 逐个移除。

注册广播(SystemUI AndroidManifest.xml

文件位置:

  • frameworks/base/packages/SystemUI/AndroidManifest.xml

application 节点中增加广播注册(示例):

1
2
3
4
5
6
7
<receiver
android:name=".receiver.KillProcessesReceiver"
android:exported="false">
<intent-filter>
<action android:name="con.yt.kill.processes" />
</intent-filter>
</receiver>

保护广播(系统 AndroidManifest.xml

文件位置:

  • frameworks/base/core/res/AndroidManifest.xml

为防止普通应用随意发送该广播,需要将其声明为受保护广播:

1
<protected-broadcast android:name="con.yt.kill.processes" />

这样,只有具有系统权限的组件才能正常发送此广播。


调用方式示例

上层只需要构造相应的 Intent,并携带白名单列表即可。例如:

1
2
3
4
5
6
7
8
public static final String ACTION_KILL_PROCESSES = "con.yt.kill.processes";

@Override
public void killBackgroundProcesses(Context context, ArrayList<String> whiteApp) {
Intent intent = new Intent(ACTION_KILL_PROCESSES);
intent.putStringArrayListExtra("whiteApp", whiteApp);
context.sendBroadcast(intent);
}

其中:

  • whiteApp:白名单列表,可填入包名或具体 Activity 类名;
  • 不在白名单中的近期任务,会被统一通过 removeTask(...) 清理掉。

至此,就实现了在 Android 7 平台上,一键清理近期任务且保留白名单应用的系统级方案。

本文链接:
http://longzhiye.top/2025/11/23/2025-11-23/