recent移除task时,结束其所有进程和service(全Android版本)

目录

一、Launcher中forceStopPackage

Android9

Android13

二、AMS中判断前台service也杀死

Android6

Android7

Android11


Android原生系统在清理后台应用时,其实并不能清理所有进程。例如:

在点击系统自带的播放器以后,播放音乐的时候,在最近任务栏recents列表中,点击全部清除,发现音乐播放器还在播放音乐。

现提供两种解决方案

一、Launcher中forceStopPackage

Android9

vendor下面的launcher 里面
RecentsView.java
TaskActionController.javaremoveTask 方法里面
-         ActivityManagerWrapper.getInstance().removeTask(task.key.id);
+        final ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
+        String pkgName = task.key.getPackageName();
+        Log.d(TAG, "Stopping pkgName " + pkgName);
+        am.forceStopPackage(pkgName);

Android13

alps_mssi/frameworks/base/data/etc/com.android.launcher3.xml<permission name="android.permission.STOP_APP_SWITCHES"/>
+               <permission name="android.permission.FORCE_STOP_PACKAGES"/>alps_mssi/vendor/mediatek/proprietary/packages/apps/Launcher3/quickstep/AndroidManifest.xml
+    <uses-permission android:name="android.permission.FORCE_STOP_PACKAGES"/>alps_mssi/vendor/mediatek/proprietary/packages/apps/Launcher3/quickstep/src/com/android/quickstep/views/RecentsView.javaimport java.util.Objects;import java.util.function.Consumer;+import android.app.ActivityManager;
+import android.app.ActivityOptions;
+/*** A list of recent tasks.*/
@@ -3127,12 +3130,16 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_Tif (success) {if (shouldRemoveTask) {if (dismissedTaskView.getTask() != null) {
+                                                       //andy
+                                                       String pkgname = dismissedTaskView.getTask().key.getPackageName();
+                                                       Log.e("andy---RecentsView","pkgname="+pkgname);
+                                                       if (ENABLE_QUICKSTEP_LIVE_TILE.get()&& dismissedTaskView.isRunningTask()) {finishRecentsAnimation(true /* toRecents */, false /* shouldPip */,
-                                        () -> removeTaskInternal(dismissedTaskViewId));
+                                        () -> removeTaskInternal(dismissedTaskViewId,pkgname));} else {
-                                removeTaskInternal(dismissedTaskViewId);
+                                removeTaskInternal(dismissedTaskViewId,pkgname);}mActivity.getStatsLogManager().logger().withItemInfo(dismissedTaskView.getItemInfo())
@@ -3401,7 +3408,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_Treturn lastVisibleIndex;}-    private void removeTaskInternal(int dismissedTaskViewId) {
+    private void removeTaskInternal(int dismissedTaskViewId, String pkgname) {int[] taskIds = getTaskIdsForTaskViewId(dismissedTaskViewId);int primaryTaskId = taskIds[0];int secondaryTaskId = taskIds[1];
@@ -3411,6 +3418,10 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_Tif (secondaryTaskId != -1) {ActivityManagerWrapper.getInstance().removeTask(secondaryTaskId);}
+                                       //andy
+                                       ActivityManager am = (ActivityManager) mActivity.getSystemService(Context.ACTIVITY_SERVICE);
+                                       Log.e("andy---RecentsView---", "pkgname = " + pkgname);
+                                       am.forceStopPackage(pkgname);                                   },REMOVE_TASK_WAIT_FOR_APP_STOP_MS);}
@@ -3436,6 +3447,12 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_Tint count = getTaskViewCount();for (int i = 0; i < count; i++) {addDismissedTaskAnimations(requireTaskViewAt(i), duration, anim);
+                       //andy
+                       String pkgname = requireTaskViewAt(i).getTask().key.getPackageName();
+                       Log.e("andy---RecentsView---createAllTasksDismissAnimation---","pkgname="+pkgname);
+                       ActivityManager am = (ActivityManager) mActivity.getSystemService(Context.ACTIVITY_SERVICE);
+                       am.forceStopPackage(pkgname);                                   
+                       }mPendingAnimation = anim;

二、AMS中判断前台service也杀死

/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

Android6

在最近的任务界面,把正在播放的音乐关掉,播放的音乐没有停止@Overridepublic boolean removeTask(int taskId) {synchronized (this) {enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,"removeTask()");long ident = Binder.clearCallingIdentity();try {return removeTaskByIdLocked(taskId, true);} finally {Binder.restoreCallingIdentity(ident);}}}private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);/// M: BMW. [ALPS01455940], remove task which not in recent task/// but we really want to remove. Add recent task will auto remove/// duplicate task record (the same task affinity) @{if (MultiWindowProxy.isSupported() && tr == null) {ArrayList<ActivityStack> stackList = mStackSupervisor.getStacks();for (int i = 0; i < stackList.size(); i++) {ActivityStack stack = stackList.get(i);TaskRecord task = stack.topTask();if (MultiWindowProxy.getInstance().isFloatingStack(stack.mStackId)&& task != null && task.taskId == taskId) {tr = task;}}}/// @}if (tr != null) {tr.removeTaskActivitiesLocked();cleanUpRemovedTaskLocked(tr, killProcess);if (tr.isPersistable) {notifyTaskPersisterLocked(null, true);}return true;}Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);return false;}private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {mRecentTasks.remove(tr);tr.removedFromRecents();ComponentName component = tr.getBaseIntent().getComponent();if (component == null) {Slog.w(TAG, "No component for base intent of task: " + tr);return;}// Find any running services associated with this app and stop if needed.mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));if (!killProcess) {return;}// Determine if the process(es) for this task should be killed.final String pkg = component.getPackageName();ArrayList<ProcessRecord> procsToKill = new ArrayList<>();ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();for (int i = 0; i < pmap.size(); i++) {SparseArray<ProcessRecord> uids = pmap.valueAt(i);for (int j = 0; j < uids.size(); j++) {ProcessRecord proc = uids.valueAt(j);if (proc.userId != tr.userId) {// Don't kill process for a different user.continue;}if (proc == mHomeProcess) {// Don't kill the home process along with tasks from the same package.continue;}if (!proc.pkgList.containsKey(pkg)) {// Don't kill process that is not associated with this task.continue;}for (int k = 0; k < proc.activities.size(); k++) {TaskRecord otherTask = proc.activities.get(k).task;if (tr.taskId != otherTask.taskId && otherTask.inRecents) {// Don't kill process(es) that has an activity in a different task that is// also in recents.return;}}if (proc.foregroundServices) {// Don't kill process(es) with foreground service.return;}// Add process to kill list.procsToKill.add(proc);}}// Kill the running processes.for (int i = 0; i < procsToKill.size(); i++) {ProcessRecord pr = procsToKill.get(i);if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE&& pr.curReceiver == null) {pr.kill("remove task", true);} else {// We delay killing processes that are not in the background or running a receiver.pr.waitingToKill = "remove task";}}}可以看到,如果是foreground的service,就不会kill掉进程让service 不调用     public final void startForeground(int id, Notification notification);问题解决但如果不调用这个,service就是后台的,系统内存紧张时就会被杀掉,后续看看有没有别的解决办法~改framework?实在不行就这么干

Android7

    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,boolean removeFromRecents) {if (removeFromRecents) {mRecentTasks.remove(tr);tr.removedFromRecents();}ComponentName component = tr.getBaseIntent().getComponent();if (component == null) {Slog.w(TAG, "No component for base intent of task: " + tr);return;}// Find any running services associated with this app and stop if needed.mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));if (!killProcess) {return;}// Determine if the process(es) for this task should be killed.final String pkg = component.getPackageName();ArrayList<ProcessRecord> procsToKill = new ArrayList<>();ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();for (int i = 0; i < pmap.size(); i++) {SparseArray<ProcessRecord> uids = pmap.valueAt(i);for (int j = 0; j < uids.size(); j++) {ProcessRecord proc = uids.valueAt(j);if (proc.userId != tr.userId) {// Don't kill process for a different user.continue;}if (proc == mHomeProcess) {// Don't kill the home process along with tasks from the same package.continue;}if (!proc.pkgList.containsKey(pkg)) {// Don't kill process that is not associated with this task.continue;}for (int k = 0; k < proc.activities.size(); k++) {TaskRecord otherTask = proc.activities.get(k).task;if (tr.taskId != otherTask.taskId && otherTask.inRecents) {// Don't kill process(es) that has an activity in a different task that is// also in recents.return;}}-                if (proc.foregroundServices) {
-                    // Don't kill process(es) with foreground service.
-                    return;
-                }// Add process to kill list.procsToKill.add(proc);}}// Kill the running processes.for (int i = 0; i < procsToKill.size(); i++) {ProcessRecord pr = procsToKill.get(i);
-            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
-                    && pr.curReceiver == null) {pr.kill("remove task", true);
-            } else {
-                // We delay killing processes that are not in the background or running a receiver.
-                pr.waitingToKill = "remove task";
-            }}}

Android11

packages/apps/Launcher3/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.javavoid removeTask(Task task, boolean killProcess, boolean removeFromRecents, String reason) {if (task.mInRemoveTask) {// Prevent recursion.return;}task.mInRemoveTask = true;try {task.performClearTask(reason);cleanUpRemovedTaskLocked(task, killProcess, removeFromRecents);mService.getLockTaskController().clearLockedTask(task);mService.getTaskChangeNotificationController().notifyTaskStackChanged();if (task.isPersistable) {mService.notifyTaskPersisterLocked(null, true);}} finally {task.mInRemoveTask = false;}}void cleanUpRemovedTaskLocked(Task task, boolean killProcess, boolean removeFromRecents) {if (removeFromRecents) {mRecentTasks.remove(task);}ComponentName component = task.getBaseIntent().getComponent();if (component == null) {Slog.w(TAG, "No component for base intent of task: " + task);return;}// Find any running services associated with this app and stop if needed.final Message msg = PooledLambda.obtainMessage(ActivityManagerInternal::cleanUpServices,mService.mAmInternal, task.mUserId, component, new Intent(task.getBaseIntent()));mService.mH.sendMessage(msg);if (!killProcess) {return;}// Determine if the process(es) for this task should be killed.final String pkg = component.getPackageName();ArrayList<Object> procsToKill = new ArrayList<>();ArrayMap<String, SparseArray<WindowProcessController>> pmap =mService.mProcessNames.getMap();for (int i = 0; i < pmap.size(); i++) {SparseArray<WindowProcessController> uids = pmap.valueAt(i);for (int j = 0; j < uids.size(); j++) {WindowProcessController proc = uids.valueAt(j);if (proc.mUserId != task.mUserId) {// Don't kill process for a different user.continue;}if (proc == mService.mHomeProcess) {// Don't kill the home process along with tasks from the same package.continue;}if (!proc.mPkgList.contains(pkg)) {// Don't kill process that is not associated with this task.continue;}if (!proc.shouldKillProcessForRemovedTask(task)) {// Don't kill process(es) that has an activity in a different task that is also// in recents, or has an activity not stopped.return;}// core modify start/*if (proc.hasForegroundServices()) {// Don't kill process(es) with foreground service.return;}*/// core modify end// Add process to kill list.procsToKill.add(proc);}}// Kill the running processes. Post on handle since we don't want to hold the service lock// while calling into AM.final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::killProcessesForRemovedTask, mService.mAmInternal,procsToKill);mService.mH.sendMessage(m);}public void killProcessesForRemovedTask(ArrayList<Object> procsToKill) {synchronized (ActivityManagerService.this) {for (int i = 0; i < procsToKill.size(); i++) {final WindowProcessController wpc =(WindowProcessController) procsToKill.get(i);final ProcessRecord pr = (ProcessRecord) wpc.mOwner;// core modify start/*if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND&& pr.curReceivers.isEmpty()) {*/pr.kill("remove task", ApplicationExitInfo.REASON_USER_REQUESTED,ApplicationExitInfo.SUBREASON_UNKNOWN, true);/* } else {// We delay killing processes that are not in the background or running a// receiver.pr.waitingToKill = "remove task";}*/
// core modify end}}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/70384.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

亲测可用,IDEA中使用满血版DeepSeek R1!支持深度思考!免费!免配置!

作者&#xff1a;程序员 Hollis 之前介绍过在IDEA中使用DeepSeek的方案&#xff0c;但是很多人表示还是用的不够爽&#xff0c;比如用CodeChat的方案&#xff0c;只支持V3版本&#xff0c;不支持带推理的R1。想要配置R1的话有特别的麻烦。 那么&#xff0c;今天&#xff0c;给…

Day6 25/2/19 WED

【一周刷爆LeetCode&#xff0c;算法大神左神&#xff08;左程云&#xff09;耗时100天打造算法与数据结构基础到高级全家桶教程&#xff0c;直击BTAJ等一线大厂必问算法面试题真题详解&#xff08;马士兵&#xff09;】https://www.bilibili.com/video/BV13g41157hK?p4&v…

centos服务器巡检脚本

服务器巡检脚本 系统负载shell脚本python将txt文件转换成excel&#xff0c;不正常巡检结果标记红色 系统负载shell脚本 #!/bin/bash#文件路径 path"/root/monitor.txt"#yum -y install bc sysstat net-tools lrzsz #获取主机名 system_hostname$(hostname | awk {pr…

大模型面经:SFT和RL如何影响模型的泛化或记忆能力?

监督微调 (SFT) 和强化学习 (RL)都是目前大模型的基础模型后训练技术&#xff0c;像DeepSeek-R1、kimi等的训练方法都将两种技术应用到了极致。 如何去设计训练步骤&#xff08;先SFT再RL&#xff0c;还是直接RL&#xff09;都需要对SFT和RL的能力有较深刻的了解。 本篇就以面…

Three.js 快速入门教程【一】开启你的 3D Web 开发之旅

系列文章目录 Three.js 快速入门教程【一】开启你的 3D Web 开发之旅 Three.js 快速入门教程【二】透视投影相机 Three.js 快速入门教程【三】渲染器 Three.js 快速入门教程【四】三维坐标系 Three.js 快速入门教程【五】动画渲染循环 Three.js 快速入门教程【六】相机控件 Or…

安全问答—安全的基本架构

前言 将一些安全相关的问答进行整理汇总和陈述&#xff0c;形成一些以问答呈现的东西&#xff0c;加入一些自己的理解&#xff0c;欢迎路过的各位大佬进行讨论和论述。很多内容都会从甲方的安全认知去进行阐述。 1.安全存在的目的&#xff1f; 为了支持组织的目标、使命和宗…

Navicat Premium17 连接Oracle出现 “未加载 Oracle库

报错信息如下 解决方案&#xff1a; 安装 Navicat for Oracle 12 for Mac 若已经打开任何来源&#xff0c;但运行还是遇到已损坏按照如下操作即可解决&#xff01; 终端中输入 xattr -cr cr 后面输入一个空格&#xff01;不要回车&#xff01;如下图 把 Navicat for Oracle…

Transformer解析——(一)概述

本系列已完结&#xff0c;全部文章地址为&#xff1a; Transformer解析——&#xff08;一&#xff09;概述-CSDN博客 Transformer解析——&#xff08;二&#xff09;Attention注意力机制-CSDN博客 Transformer解析——&#xff08;三&#xff09;Encoder-CSDN博客 Transforme…

Qt的QToolButton的使用

在C中使用QToolButton的详细步骤如下&#xff1a; 1. 包含头文件 #include <QToolButton> #include <QAction> #include <QMenu>2. 创建QToolButton实例 QToolButton *toolButton new QToolButton(parentWidget); // parentWidget为父部件指针3. 基础属性…

Canvas进阶-2、可视化应用

前言 Canvas 可以用来创建各种 数据可视化 图表和图形&#xff0c;通过绘制不同的形状、线条和颜色来展示数据的特征和趋势。 数据可视化的基本原理是将数据转化为可视化的图形元素&#xff0c;以便人们更容易理解和分析数据。这涉及到以下几个方面&#xff1a; 数据映射&…

力扣-回溯-17 电话号码的字母组合

思路 和之前的回溯不同的是&#xff0c;要遍历完所有的数字&#xff0c;并且在单层递归逻辑里需要遍历一整个字符串 代码 class Solution { public:vector<string> letters {"", "", "abc", "def", "ghi", "…

Windows11切换回Windows10风格右键菜单

参考文章&#xff1a;Win11新版右键菜单用不惯&#xff1f;一键切换回Win10经典版&#xff01;-CSDN博客 以管理员权限运行命令行cmd 切换为经典旧版右键菜单&#xff0c;执行 reg.exe add “HKCU\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServe…

小米AX3000T 路由器如何开启 SSH 安装 OpenWRT 系统,不需要降级 v1.0.91 (2025)

小米AX3000T 路由器如何开启 SSH 安装 OpenWRT 系统&#xff0c;不需要降级 v1.0.91 &#xff08;2025&#xff09; 本文内容需要你有一定的 Linux 操作基础&#xff0c;最好是程序员那种&#xff0c;英文水平足够用才行。一般人不需要使用这么复杂的路由器操作系统&#xff0c…

Linux自学day23-进程和线程

1. 什么是进程&#xff1f; 进程是程序执行的过程&#xff0c;涵盖创建、调度和消亡阶段&#xff0c;是活的。 而程序是一段数据的集合&#xff0c;是死的。 进程还是操作系统资源分配的最小单元&#xff0c;拥有独立的虚拟地址空间&#xff0c;包括文本段、数据段、系统数据…

python查错误TypeError: bad operand type for unary -: ‘str‘

TypeError: bad operand type for unary -: str​​​ 这个错误表明尝试对一个字符串类型的数据使用一元减号运算符&#xff08;​​-​​&#xff09;&#xff0c;而在 Python 中&#xff0c;一元减号运算符只能用于数值类型&#xff08;如整数、浮点数等&#xff09;&#xf…

常用的性能优化方法和技巧

常用的性能优化方法和技巧 前端性能优化 减少HTTP请求&#xff1a;就好比你去超市买东西&#xff0c;每次请求就像你跑一趟超市。去的次数越多&#xff0c;花在路上的时间就越多。所以把多个小的资源&#xff0c;像图片、脚本这些&#xff0c;合并成一个大的&#xff0c;就能…

网络协议相关知识有哪些?

前言 网络协议的基础是OSI和TCP/IP模型,这两个模型是理解协议分层的关键。 正文(仅是个人理解,如有遗漏望海涵) 网络协议是网络中设备间通信的规则和标准,涉及数据传输、路由、错误控制等多个方面。以下是网络协议相关知识的系统梳理: 一、网络协议分层模型 1、OSI七…

鸿蒙初学者学习手册(HarmonyOSNext_API14)_自定义动画API(@ohos.animator (动画) )

前言 在纯血鸿蒙中最具有用户特色的效果就是自定义的动画效果。在纯血鸿蒙中有多种定义方式&#xff0c;但是今天介绍的是ApI中的自定义动画。 注意: 动画本身具有生命周期&#xff0c;但是不支持在UIAbility的文件使用&#xff0c;简单而言就是不允许在UIAbility生命周期中…

搭建Kubernetes (K8s) 集群----Centos系统

前期准备 准备3台Linux虚拟机&#xff08;CentOS系统&#xff09;&#xff0c;参考 https://carry.blog.csdn.net/article/details/144578009https://carry.blog.csdn.net/article/details/144578009搭建Docker环境&#xff0c;参考 https://carry.blog.csdn.net/article/de…

wps中的js开发

严格区分大小写 /*** learn_js Macro*/ function test() {Range(D7).Value2Selection.Value2; // Selection.formula "100" }function Workbook_SheetSelectionChange(Sh, Target) {if(Sh.Name Sheet1) {test();}}function test2() {// 把I4单元格及其周边有数的单…