20251028在荣品RD-RK3588-MID开发板的Android13系统下消除关机的时候最近打开的应用不关的问题
2025/10/28 18:12
缘起:公司的APK应用开发工程师的需求/品味/审美比较独特,报告了超多问题。!
要求关机/poweroff的时候,最近打开的应用也要清除。
直接调用“全部清除”不就得了。
源码由DeepSeek给出来!
测试设备:Android手机【版本10+】、荣品RD-RK3588-MID开发板
测试步骤:按 虚拟按键,左下角的 3条横线,看看 打开了几个应用。
长按 POWER按键 重启。
重启完成 之后,继续 按 虚拟按键的 ,允许看见 以前的应用还在![破涕为笑]
好的,你这边测试是软重启是吧,
你能够试一下断电硬重启
测试设备:Android手机【版本10+】、荣品RD-RK3588-MID开发板
测试步骤:按 虚拟按键,左下角的 3条横线,看看 打开了几个应用。
长按 POWER按键 【上一次重启,这一次 关机 也有】。
重启完成 之后,继续 按 虚拟按键的 ,可以看见 以前的应用还在![破涕为笑]?
POWEROFF也有这个障碍 有点说不过去了。[疑问]
是否是 RK/Android的问题?
如果 是 Android的问题?请问 如何在poweroff走关机的流程之前,调用【全部清除,干掉所有的APP】[破涕为笑]?
ZT10/28 10:17:12
有个小问题 开机重启 Home 会看到上次的记录
ZT 10/28 10:17:22
关机,再开机
这个 难题 非 致命性 BUG/不影响能力,记录在案,押后处理。
RK/Android的问题?就是先要要确认 是否
Android的问题?【解决思路之一】 如何在poweroff走关机的流程之前,调用【全部清除,干掉所有的APP】[破涕为笑]?@余顺就是倘若
第一步:
RK3588 Android13关机清除APP方案
在RK3588的Android13关机的时候,请问如何 修改SDK代码,以调用 “全部清除” 拿掉所有历史打开的APP,
方案一:修改ActivityManagerService(推荐)
1. 修改文件:
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
2. 添加清除方法:
java
// 在ActivityManagerService类中添加方法
private void clearAllRecentTasksOnShutdown() {
try {
// 获取ActivityTaskManager服务
IActivityTaskManager atm = ActivityTaskManager.getService();
if (atm != null) {
// 移除所有最近任务
atm.removeAllVisibleRecentTasks();
// 或者使用以下办法清除所有任务
// List<ActivityManager.RecentTaskInfo> recentTasks =
// getRecentTasks(Integer.MAX_VALUE, 0, userId);
// for (ActivityManager.RecentTaskInfo task : recentTasks) {
// removeTask(task.persistentId);
// }
Slog.i(TAG, "Cleared all recent tasks on shutdown");
}
} catch (RemoteException e) {
Slog.e(TAG, "Failed to clear recent tasks on shutdown", e);
}
}
3. 在关机流程中调用:
在shutdown()方法中添加调用:
java
@Override
public void shutdown(int timeout) {
// 先清除所有最近任务
clearAllRecentTasksOnShutdown();
// 原有关机代码
// ... existing shutdown code ...
}
编译的时候出错:
请复核一下方法一的代码:
warning: Supported source version 'RELEASE_9' from annotation processor 'android.processor.compat.changeid.ChangeIdProcessor' less than -source '11'
out/soong/.intermediates/frameworks/base/services/core/services.core.unboosted/android_common/javac/shard32/srcjars/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java:6896: error: cannot find symbol
IActivityTaskManager atm = ActivityTaskManager.getService();
^
symbol: class IActivityTaskManager
location: class ActivityManagerService
out/soong/.intermediates/frameworks/base/services/core/services.core.unboosted/android_common/javac/shard32/srcjars/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java:6896: error: cannot find symbol
IActivityTaskManager atm = ActivityTaskManager.getService();
^
symbol: variable ActivityTaskManager
location: class ActivityManagerService
2 errors
1 warning
16:43:32 ninja failed with: exit status 1
#### failed to build some targets (02:12 (mm:ss)) ####
Build android failed!
rootroot@rootroot-X99-Turbo:~/rk-android13-20250818RD-RK3588-MID$


您遇到的编译错误是因为缺少正确的导入。让我给出修正后的代码:
修正后的方案一代码
1. 开始添加必要的导入
在 ActivityManagerService.java 记录的开头添加以下导入:
java
import android.app.ActivityTaskManager;
import android.app.IActivityTaskManager;
2. 修正的清除方法
java
// 在ActivityManagerService类中添加方法
private void clearAllRecentTasksOnShutdown() {
try {
// 使用正确的方式获取ActivityTaskManager服务
IActivityTaskManager atm = ActivityTaskManager.getService();
if (atm != null) {
// 移除所有最近任务
atm.removeAllVisibleRecentTasks();
Slog.i(TAG, "Cleared all recent tasks on shutdown");
}
} catch (RemoteException e) {
Slog.e(TAG, "Failed to clear recent tasks on shutdown", e);
}
}
3. 在shutdown方法中调用
找到 shutdown 方法,在方法开始处添加调用:
java
@Override
public boolean shutdown(int timeout) {
// 在关机时清除所有最近任务
clearAllRecentTasksOnShutdown();
// 原有的shutdown代码保持不变
// ... existing shutdown code ...
return true;
}


效果图:



RK3588 Android13关机清除APP方案
在RK3588的Android13关机的时候,请问如何 修改SDK代码,以调用 “全部清除” 拿掉所有历史打开的APP,
在Android系统中,关机过程会发送关机广播,然后框架会关闭所有活动。但是,默认情况下,系统并不会在关机时清除所有最近任务(即历史打开的APP)。如果你想要在关机时清除所有最近任务,你应该修改架构代码。
在Android中,最近任务(Recent Tasks)是由SystemUI管理的。因此,我们可以在关机过程中通知SystemUI清除最近任务。
以下是一种可能的实现技巧:
第一,我们需要在关机流程中找到一个合适的点来触发清除最近任务的操作。在Android中,关机时会发送Intent.ACTION_SHUTDOWN广播,我们允许监听这个广播,可是这里我们需要在系统代码中直接添加调用,因为我们需要系统权限。
另一种手段是在ShutdownThread中添加代码,源于关机流程是由ShutdownThread控制的。
我们也允许考虑在ActivityManagerService中添加清除最近任务的功能,因为ActivityManagerService负责管理Activity和任务。
这里我们选择在ShutdownThread中添加代码,源于它是直接处理关机流程的。
具体步骤:
a. 找到ShutdownThread类。在AOSP中,这个类通常位于frameworks/base/services/core/java/com/android/server/power/ShutdownThread.java。
b. 在ShutdownThread的run()办法中,在关机流程的某个阶段(例如,在广播关机意图之后,但在真正关闭电源之前)添加清除最近任务的代码。
c. 清除最近任务行通过ActivityManagerService的removeAllTasks()技巧来实现。但是请注意,removeAllTasks()方法可能会被限制,因此我们需要检查可用性。
实际上,在Android中,我们允许启用ActivityManager的removeTask或removeAllTasks方法,不过这些方法需系统权限。在系统代码中,我们能够直接调用。
在ShutdownThread中,大家允许通过IActivityManager来调用清除任务的方法。
ActivityManager。就是d. 但是,请注意,从Android 5.0开始,Google对最近任务的管理做了更改,我们可能需运用ActivityTaskManager而不
由于我们是在RK3588的Android13上修改,所以我们需要使用新的API。
在Android 10及以上,最近任务的管理在ActivityTaskManager中。大家可以通过ActivityTaskManager的removeAllVisibleRecentTasks()方法来清除最近任务。
,请注意,ShutdownThread中可能没有直接引用ActivityTaskManager,我们需要添加相应的导入和调用。就是但
具体代码修改:
在ShutdownThread.java文件中,添加导入:
java
import android.app.ActivityTaskManager;
import android.content.Context;
在run()方法中,在广播关机意图之后,添加以下代码:
java
// Clear all recent tasks
try {
ActivityTaskManager atm = (ActivityTaskManager) Context.getSystemService(Context.ACTIVITY_TASK_SERVICE);
if (atm != null) {
atm.removeAllVisibleRecentTasks();
}
} catch (Exception e) {
Log.e(TAG, "Failed to clear recent tasks", e);
}
一个系统API,需要系统权限。由于ShutdownThread运行在系统进程中,所以应该有权调用。就是可是,请注意,ActivityTaskManager的removeAllVisibleRecentTasks()方法
然而,实际上,在Android 13中,ActivityTaskManager并没有提供removeAllVisibleRecentTasks()方法。相反,大家允许使用ActivityTaskManager的removeAllRecentTasks()方法,但是这个方法在Android 13中已经被隐藏,并且必须系统权限。
另一种办法是运用IActivityTaskManager接口,通过AIDL调用。只是,我们也可能使用ActivityManager的clearRecentTasks()方法,不过这个方法在Android 5.0之后被标记为隐藏。
考虑到这些,我们可以依据反射来调用,但更稳定的方法是启用系统内部API。
在关机流程中,我们可以直接调用ActivityManagerService的相关方法。就是实际上,在Android系统中,SystemUI中的RecentTasks类负责管理最近任务。但是,我们这里
由于我们是在体系服务器中,我们可以直接获取ActivityManagerService的实例并调用其方法。
通过,IActivityManager接口中并没有直接清除最近任务的方法。就是在ShutdownThread中,我们能够通过ActivityManager.getService()来获取IActivityManager,然后调用其方法。但
我们可以通过调用IActivityManager的removeTask方法遍历删除所有任务,但是这样效率低且复杂。
另一种方法是,我们直接调用ActivityTaskManagerService的removeAllRecentTasks()方法。但,我们需要获取到ActivityTaskManagerService的实例。
在平台代码中,我们可能通过ActivityTaskManager.getService()来获取IActivityTaskManager,接着调用removeAllRecentTasks()。
但是,removeAllRecentTasks()方法在IActivityTaskManager中是有定义的,但是它是一个环境API,并且应该系统权限。
通过我们能够这样写:
java
IActivityTaskManager atm = ActivityTaskManager.getService();
if (atm != null) {
atm.removeAllRecentTasks();
}
可是,请注意,removeAllRecentTasks()方法可能会抛出RemoteException,我们需要处理。
所以,修改后的代码可能如下:
在ShutdownThread.java的run()方法中,在广播关机意图之后,添加:
java
// Clear all recent tasks
try {
IActivityTaskManager atm = ActivityTaskManager.getService();
if (atm != null) {
atm.removeAllRecentTasks();
}
} catch (RemoteException e) {
Log.e(TAG, "Failed to clear recent tasks", e);
}
同时,需要导入:
java
import android.app.ActivityTaskManager;
import android.app.IActivityTaskManager;
import android.os.RemoteException;
但是,请注意,removeAllRecentTasks()方法在Android 13中可能被限制,得系统权限。由于ShutdownThread运行在系统进程,所以应该可以调用。
另外,请注意,这个手段会清除所有最近任务,包括默认的launcher任务,所以下次开机时,launcher会重新启动。
最后,由于大家修改了环境代码,要求重新编译系统并刷机。
基于AOSP的代码结构,具体在RK3588的SDK中,可能会有一些差异,请根据实际情况调整。就是注意:以上代码
另外,RK3588的SDK可能对关机流程有自定义的修改,所以请确保在修改时不会影响其他关机流程。
由于关机流程是系统关键流程,请谨慎修改,并充分测试。
在RK3588的Android 13上构建关机时清除所有历史打开的APP,你需要修改系统服务代码。以下是几种建立方案:
方案一:修改ActivityManagerService(推荐)
1. 修改文件:
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
2. 添加清除方法:
java
// 在ActivityManagerService类中添加技巧
private void clearAllRecentTasksOnShutdown() {
try {
// 获取ActivityTaskManager服务
IActivityTaskManager atm = ActivityTaskManager.getService();
if (atm != null) {
// 移除所有最近任务
atm.removeAllVisibleRecentTasks();
// 或者运用以下方法清除所有任务
// List<ActivityManager.RecentTaskInfo> recentTasks =
// getRecentTasks(Integer.MAX_VALUE, 0, userId);
// for (ActivityManager.RecentTaskInfo task : recentTasks) {
// removeTask(task.persistentId);
// }
Slog.i(TAG, "Cleared all recent tasks on shutdown");
}
} catch (RemoteException e) {
Slog.e(TAG, "Failed to clear recent tasks on shutdown", e);
}
}
3. 在关机流程中调用:
在shutdown()方法中添加调用:
java
@Override
public void shutdown(int timeout) {
// 先清除所有最近任务
clearAllRecentTasksOnShutdown();
// 原有关机代码
// ... existing shutdown code ...
}
方案二:修改ShutdownThread
1. 修改文件:
frameworks/base/services/core/java/com/android/server/power/ShutdownThread.java
2. 在beginShutdown()技巧中添加:
java
private static void beginShutdown() {
// 在关机开始时清除最近任务
clearAllRecentTasks();
// 原有代码
// ... existing code ...
}
private static void clearAllRecentTasks() {
try {
IActivityTaskManager atm = ActivityTaskManager.getService();
if (atm != null) {
// 清除所有可见的最近任务
atm.removeAllVisibleRecentTasks();
// 强制停止所有后台进程
ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
if (am != null) {
am.forceStopPackage(mContext.getPackageName());
}
}
} catch (Exception e) {
Log.e(TAG, "Failed to clear recent tasks during shutdown", e);
}
}
方案三:修改RecentTasks.java
1. 修改材料:
frameworks/base/services/core/java/com/android/server/wm/RecentTasks.java
2. 添加关机清理途径:
java
public void cleanupOnShutdown() {
synchronized (mService) {
// 清除所有任务
for (int i = mTasks.size() - 1; i >= 0; i--) {
Task task = mTasks.get(i);
removeTask(task);
}
// 清除持久化数据
mTaskPersister.unloadAllData();
// 保存空的任务列表
mTaskPersister.persistTasks(null);
}
}
方案四:通过广播接收器(倘若权限允许)
1. 创建关机广播接收器:
java
public class ShutdownClearReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
clearAllRecentTasks(context);
}
}
private void clearAllRecentTasks(Context context) {
try {
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
// 通过ActivityManager清除任务
if (am != null) {
// 该方法可能需要系统权限
Method method = am.getClass().getMethod("removeAllVisibleRecentTasks");
method.invoke(am);
}
} catch (Exception e) {
Log.e("ShutdownClear", "Failed to clear recent tasks", e);
}
}
}
完整实现建议:
我建议采用方案一,因为它最直接且权限足够。具体搭建步骤:
在ActivityManagerService.java的shutdown()方法开始处添加:
java
@Override
public boolean shutdown(int timeout) {
// 清除所有最近任务
clearAllRecentTasksOnShutdown();
// 原有关机逻辑
return super.shutdown(timeout);
}
建立clearAllRecentTasksOnShutdown()途径:
java
private void clearAllRecentTasksOnShutdown() {
synchronized (this) {
try {
// 获取所有用户
int[] userIds = mUserController.getUserIds();
for (int userId : userIds) {
// 清除该用户的所有最近任务
removeAllTasksForUser(userId);
}
Slog.i(TAG, "Cleared all recent tasks for all users on shutdown");
} catch (Exception e) {
Slog.e(TAG, "Error clearing recent tasks on shutdown", e);
}
}
}
private void removeAllTasksForUser(int userId) {
// 实现具体的任务清除逻辑
// 这里必须根据你的Android版本调整具体实现
}
编译和测试:
修改做完后,重新编译系统:
bash
source build/envsetup.sh
lunch rk3588-userdebug # 根据你的实际配置
make -j8
刷机测试关机功能
注意:这些修改需系统级权限,请确保在环境签名或eng/userdebug版本上测试。生产版本可能需要额外的权限处理。
请复核一下方法一的代码:
warning: Supported source version 'RELEASE_9' from annotation processor 'android.processor.compat.changeid.ChangeIdProcessor' less than -source '11'
out/soong/.intermediates/frameworks/base/services/core/services.core.unboosted/android_common/javac/shard32/srcjars/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java:6896: error: cannot find symbol
IActivityTaskManager atm = ActivityTaskManager.getService();
^
symbol: class IActivityTaskManager
location: class ActivityManagerService
out/soong/.intermediates/frameworks/base/services/core/services.core.unboosted/android_common/javac/shard32/srcjars/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java:6896: error: cannot find symbol
IActivityTaskManager atm = ActivityTaskManager.getService();
^
symbol: variable ActivityTaskManager
location: class ActivityManagerService
2 errors
1 warning
16:43:32 ninja failed with: exit status 1
#### failed to build some targets (02:12 (mm:ss)) ####
Build android failed!
rootroot@rootroot-X99-Turbo:~/rk-android13-20250818RD-RK3588-MID$
我们遇到了编译错误,因为无法找到IActivityTaskManager和ActivityTaskManager。在Android 13中,ActivityTaskManager相关的类可能已经被移动或更改。我们需要使用正确的方法来获取ActivityTaskManager服务。
在Android 10及以上,ActivityTaskManager是一个系统服务,我们可以通过ActivityTaskManager.getService()来获取其接口,然而需要导入相应的包。
但,在ActivityManagerService中,可能已经有一个mActivityTaskManager的实例,大家可以使用它。倘若没有,我们能够通过ActivityTaskManager.getService()来获取,但应该注意导入正确的类。
大家来看一下正确的导入和用法:
首先,我们需要在ActivityManagerService.java记录的开头添加导入:
import android.app.ActivityTaskManager;
import android.app.IActivityTaskManager;
但是,要是代码中已经存在这些导入,那么可能是其他问题。如果不存在,添加它们。
然而,在Android 13的代码中,ActivityManagerService可能已经使用mActivityTaskManager来调用相关技巧。我们可以查看是否有mActivityTaskManager该成员变量。
通过假设存在mActivityTaskManager,我们能够直接采用它。
我们可以修改方法一,使用mActivityTaskManager来清除最近任务。
另外,我们也能够应用ActivityManagerService内部的方法来清除最近任务,比如通过mRecentTasks来清除。
让我们考虑一个更安全的方法:使用ActivityManagerService内部的mRecentTasks。
在ActivityManagerService中,有一个成员变量mRecentTasks,它是RecentTasks类的实例。我们可能凭借它来清除最近任务。
我们允许这样达成:
在ActivityManagerService中添加一个方法:
private void clearAllRecentTasksOnShutdown() {
synchronized (this) {
// 清除所有最近任务
mRecentTasks.cleanupOnShutdown();
}
}
然后,我们需要在RecentTasks类中实现cleanupOnShutdown方法(方案三中我们提到了RecentTasks.java的修改)。
但是,假设我们不想修改RecentTasks类,我们也可以直接调用RecentTasks的现有方法。
大家可以查看RecentTasks类中是否有清除所有任务的方法。假如没有,我们可以依据循环移除所有任务。
在RecentTasks中,有一个mTasks列表,我们可以通过移除所有任务来实现。
可是,请注意,我们可能需考虑多用户的情况。
因此,我们可以这样搭建:
private void clearAllRecentTasksOnShutdown() {
synchronized (this) {
// 获取所有最近任务并移除
List<Task> tasks = mRecentTasks.getTasks();
for (int i = tasks.size() - 1; i >= 0; i--) {
Task task = tasks.get(i);
// 移除任务
mRecentTasks.removeTask(task);
}
}
}
但是,请注意,getTasks()可能返回一个不可修改的列表,或者我们移除任务时可能会影响循环。因此,我们可以应用一个临时列表。
通过另外,我们也能够使用ActivityManagerService中已有的方法,例如removeAllVisibleRecentTasks。
实际上,ActivityManagerService中有一个removeAllVisibleRecentTasks方法,我们允许直接调用它。
通过我们能够这样:
private void clearAllRecentTasksOnShutdown() {
try {
removeAllVisibleRecentTasks();
} catch (RemoteException e) {
Slog.e(TAG, "Failed to clear recent tasks on shutdown", e);
}
}
只是,removeAllVisibleRecentTasks技巧可能会受到权限检查,我们需要确保在系统进程中运行,并且具有足够的权限。
由于我们是在体系关机时调用,而且是在ActivityManagerService内部,所以权限应该足够。
通过因此,我们能够直接调用removeAllVisibleRecentTasks。
那么,我们修改方法一:
在ActivityManagerService的shutdown方法中,在调用super.shutdown之前,调用clearAllRecentTasksOnShutdown。
然后,clearAllRecentTasksOnShutdown方法实现为:
private void clearAllRecentTasksOnShutdown() {
try {
removeAllVisibleRecentTasks();
} catch (RemoteException e) {
// 忽略异常,或者打印日志
Slog.e(TAG, "Failed to clear recent tasks on shutdown", e);
}
}
可是,removeAllVisibleRecentTasks方法可能会要求调用者具有权限,并且可能会检查调用者的身份。我们可以在ActivityManagerService内部找到一个类似的方法,看看它是如何实现的。
我们也可能看到,removeAllVisibleRecentTasks方法在ActivityManagerService中已经存在,它是一个Binder方法,通常被框架UI调用。
我们可以直接调用它,缘于我们现在就在ActivityManagerService中。
所以,我们不得利用IActivityTaskManager,而是直接调用自己的途径。
因此,我们修改方案一:
在ActivityManagerService.java中:
在shutdown手段中调用clearAllRecentTasksOnShutdown。
搭建clearAllRecentTasksOnShutdown,直接调用removeAllVisibleRecentTasks。
只是,注意removeAllVisibleRecentTasks手段需要传入一个调用者的userId,我们能够从Binder.getCallingUserId()获取,但在关机时,我们可能没有调用者。我们可以使用当前用户。
我们看一下removeAllVisibleRecentTasks方法的定义:
@Override
public void removeAllVisibleRecentTasks() throws RemoteException {
...
}
通过它没有参数,所以大家能够直接调用。
,大家看一下ActivityManagerService中的removeAllVisibleRecentTasks完成:就是但
@Override
public void removeAllVisibleRecentTasks() {
...
}
它内部会处理多用户吗?大家看一下代码。
在Android 13的ActivityManagerService中,removeAllVisibleRecentTasks途径会清除当前用户的所有可见最近任务。它通过mRecentTasks来移除任务。
通过因此,大家能够直接调用它。
所以,我们修改代码:
在ActivityManagerService的shutdown办法中:
@Override
public boolean shutdown(int timeout) {
clearAllRecentTasksOnShutdown();
return super.shutdown(timeout);
}
private void clearAllRecentTasksOnShutdown() {
try {
removeAllVisibleRecentTasks();
} catch (Exception e) {
Slog.e(TAG, "Failed to clear recent tasks on shutdown", e);
}
}
本地调用。就是但是,注意:removeAllVisibleRecentTasks方法可能会抛出RemoteException,但是我们在ActivityManagerService内部调用,实际上不会抛出RemoteException,因为它
因此,大家可以不捕获RemoteException,而是捕获Exception。
另外,大家也可以考虑清除所有用户的任务,而不仅仅是当前用户。但是,removeAllVisibleRecentTasks可能只清除当前用户的任务。如果我们想要清除所有用户的任务,我们得循环所有用户。
针对整个设备的。就是然而,在关机时,我们可能只得清除当前用户的任务,因为关机
通过如果我们想要清除所有用户的任务,我们能够这样做:
private void clearAllRecentTasksOnShutdown() {
try {
// 获取所有用户
int[] userIds = mUserController.getUserIds();
for (int userId : userIds) {
// 切换到每个用户,然后清除任务
removeAllVisibleRecentTasksForUser(userId);
}
} catch (Exception e) {
Slog.e(TAG, "Failed to clear recent tasks on shutdown", e);
}
}
但是,ActivityManagerService中可能没有removeAllVisibleRecentTasksForUser方法,我们可以通过mRecentTasks来清除指定用户的任务。
大家可以查看RecentTasks类中是否有清除指定用户任务的技巧。
假如没有,我们可以借助循环mRecentTasks中的任务,并移除指定用户的任务。
可是,为了简单起见,大家假设关机时只要求清除当前用户的任务。因为通常设备在关机时,当前用户就是主要用户。
通过如果我们坚持要清除所有用户的任务,我们能够这样:
private void clearAllRecentTasksOnShutdown() {
synchronized (this) {
// 获取所有用户
int[] userIds = mUserController.getUserIds();
for (int userId : userIds) {
// 清除该用户的所有任务
mRecentTasks.removeTasksForUser(userId);
}
}
}
包权限的,我们可以调用。就是但是,我们需要查看RecentTasks类中是否有removeTasksForUser方式。在Android 13中,RecentTasks类有一个removeTasksForUser方法,但是它
因而,我们可以这样写。
但是,我们也允许看到,在ActivityManagerService中,有一个方法removeTasksByPackageName,它内部调用了mRecentTasks.removeTasksForUser(userId, packageName)。所以我们也可以仿照它。
但是,我们想要移除所有任务,于是我们可能直接调用mRecentTasks.removeTasksForUser(userId)来移除该用户的所有任务。
大家看一下RecentTasks的removeTasksForUser方法:
void removeTasksForUser(int userId) {
// 移除该用户的所有任务
for (int i = mTasks.size() - 1; i >= 0; i--) {
Task task = mTasks.get(i);
if (task.mUserId == userId) {
removeTask(task);
}
}
}
只是,大家可能没有权限直接调用removeTasksForUser,因为它是RecentTasks的方法,并且是包权限。但是ActivityManagerService和RecentTasks在同一个包中,所以可以调用。
因此,我们可以使用mRecentTasks.removeTasksForUser(userId)来清除每个用户的任务。
因此,我们修改clearAllRecentTasksOnShutdown:
private void clearAllRecentTasksOnShutdown() {
synchronized (this) {
int[] userIds = mUserController.getUserIds();
for (int userId : userIds) {
mRecentTasks.removeTasksForUser(userId);
}
}
}
但是,大家需要注意,mRecentTasks可能为null,或者mUserController可能为null。我们许可在初始化之后调用。
由于关机时这些服务都已经初始化,故而应该没难题。
综上所述,我建议运用清除所有用户的任务的技巧。
因此,我们修改ActivityManagerService的shutdown方法,在其中调用clearAllRecentTasksOnShutdown,然后完成clearAllRecentTasksOnShutdown为清除所有用户的任务。
如果编译时发现mRecentTasks没有removeTasksForUser方法,我们许可查看RecentTasks类中可用的方法,或者通过循环mRecentTasks中的任务来逐个移除。
如果RecentTasks中没有removeTasksForUser,大家允许这样:
private void clearAllRecentTasksOnShutdown() {
synchronized (this) {
// 获取所有任务
List<Task> tasks = mRecentTasks.getTasks();
for (int i = tasks.size() - 1; i >= 0; i--) {
Task task = tasks.get(i);
mRecentTasks.removeTask(task);
}
}
}
但是,这样可能会在循环移除时修改列表,所以使用从后往前遍历。
大家选择一种实现。
通过由于我们不确定RecentTasks的具体实现,我们能够采用最直接的方式:循环移除所有任务。
所以,我们修改代码:
private void clearAllRecentTasksOnShutdown() {
synchronized (this) {
// 获取所有任务
List<Task> tasks = mRecentTasks.getTasks();
for (int i = tasks.size() - 1; i >= 0; i--) {
Task task = tasks.get(i);
mRecentTasks.removeTask(task);
}
}
}
从后往前,因而不会影响。就是但是,我们需要注意,getTasks()返回的任务列表可能是快照,我们移除任务时,mRecentTasks内部的列表会变化,但是我们的循环
安全的。就是另外,我们也可以使用迭代器,只是这里我们使用索引从后往前
因此,大家采用这个达成。
现在,我们重新编译。
不过,我们可能会遇到Task类找不到的问题。我们需要导入Task类。
在ActivityManagerService的导入中添加:
import com.android.server.wm.Task;
但是,如果Task类不在同一个包中,我们需要导入正确的包。
在ActivityManagerService中,Task的完整路径可能是:com.android.server.wm.Task
我们查看一下导入是否已经存在,假设不存在,添加它。
如果编译通过,那么我们就实现了关机清除所有最近任务的效果。
如果仍然有错误,我们可能需要调整代码。
总结步骤:
在ActivityManagerService.java的shutdown方法中,在调用super.shutdown之前,调用clearAllRecentTasksOnShutdown。
实现clearAllRecentTasksOnShutdown方法,应用同步块,循环mRecentTasks.getTasks(),逐个移除任务。
确保导入了Task类。
不推荐,因为这样破坏了封装。就是如果mRecentTasks没有getTasks途径,我们可以直接使用mRecentTasks的成员变量mTasks,但
我们查看RecentTasks类,它有一个getTasks方法,返回List<Task>。
所以,我们使用getTasks方法。
现在,大家修改代码,并重新编译。
您遇到的编译错误是因为缺少正确的导入。让我提供修正后的代码:
修正后的方案一代码
1. 开始添加必要的导入
在 ActivityManagerService.java 档案的开头添加以下导入:
java
import android.app.ActivityTaskManager;
import android.app.IActivityTaskManager;
2. 修正的清除方法
java
// 在ActivityManagerService类中添加方法
private void clearAllRecentTasksOnShutdown() {
try {
// 应用正确的方式获取ActivityTaskManager服务
IActivityTaskManager atm = ActivityTaskManager.getService();
if (atm != null) {
// 移除所有最近任务
atm.removeAllVisibleRecentTasks();
Slog.i(TAG, "Cleared all recent tasks on shutdown");
}
} catch (RemoteException e) {
Slog.e(TAG, "Failed to clear recent tasks on shutdown", e);
}
}
3. 在shutdown办法中调用
找到 shutdown 方法,在方法开始处添加调用:
java
@Override
public boolean shutdown(int timeout) {
// 在关机时清除所有最近任务
clearAllRecentTasksOnShutdown();
// 原有的shutdown代码保持不变
// ... existing shutdown code ...
return true;
}
备选方案:利用现有途径
如果上面的途径仍有问题,可以利用ActivityManagerService内部的现有方法:
方案一A:使用removeAllRecentTasks方法
java
private void clearAllRecentTasksOnShutdown() {
try {
// 直接调用ActivityManagerService内部的方法
removeAllRecentTasks();
Slog.i(TAG, "Cleared all recent tasks on shutdown");
} catch (Exception e) {
Slog.e(TAG, "Failed to clear recent tasks on shutdown", e);
}
}
方案一B:通过RecentTasks清理
java
private void clearAllRecentTasksOnShutdown() {
synchronized (this) {
try {
// 通过mRecentTasks清理
if (mRecentTasks != null) {
// 获取所有任务并清除
List<ActivityManager.RecentTaskInfo> tasks = getRecentTasks(
Integer.MAX_VALUE, 0, UserHandle.USER_ALL);
for (ActivityManager.RecentTaskInfo task : tasks) {
removeTask(task.persistentId);
}
Slog.i(TAG, "Cleared all recent tasks on shutdown");
}
} catch (Exception e) {
Slog.e(TAG, "Failed to clear recent tasks on shutdown", e);
}
}
}
方案二:修改ShutdownThread(推荐备选)
如果ActivityManagerService修改仍有问题,建议使用ShutdownThread方案:
修改文件:
frameworks/base/services/core/java/com/android/server/power/ShutdownThread.java
在beginShutdown方式中添加:
java
private static void beginShutdown() {
// 在关机开始时清除最近任务
clearAllRecentTasks();
// 原有代码保持不变
// ... existing code ...
}
private static void clearAllRecentTasks() {
try {
// 通过ActivityManager清除任务
ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
if (am != null) {
// 使用反射调用系统技巧
Method method = am.getClass().getMethod("removeAllVisibleRecentTasks");
if (method != null) {
method.invoke(am);
Log.i(TAG, "Cleared all recent tasks on shutdown");
}
}
} catch (Exception e) {
Log.e(TAG, "Failed to clear recent tasks during shutdown", e);
}
}
编译前检查
在编译前,请确保:
检查导入:确认所有使用的类都已正确导入
检查方法存在:在源码中搜索确保启用的方法确实存在
权限检查:确保代码有足够的系统权限
推荐的完整实现
我建议先尝试方案一A,因为它最简洁:
java
// 在ActivityManagerService.java的shutdown方式开始处添加:
@Override
public boolean shutdown(int timeout) {
// 清除所有最近任务
try {
removeAllRecentTasks();
Slog.i(TAG, "Cleared all recent tasks on shutdown");
} catch (Exception e) {
Slog.e(TAG, "Failed to clear recent tasks on shutdown", e);
}
// 原有shutdown逻辑
return super.shutdown(timeout);
}
假如仍有编译问题,请提供具体的错误信息,我允许进一步帮您调整。