【阅读笔记】Android AMS forcestop停止应用

news/2024/12/19 16:00:37/

根据这篇文章作的笔记

基于Android 12的force-stop流程分析_android forcestop-CSDN博客

在AMS中,停止指定的应用是一个常用的功能,在代码里可以看到

    @Override
6806    public void forceStopPackage(final String packageName, int userId) {
6807        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
6808                != PackageManager.PERMISSION_GRANTED) {
6809            String msg = "Permission Denial: forceStopPackage() from pid="
6810                    + Binder.getCallingPid()
6811                    + ", uid=" + Binder.getCallingUid()
6812                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
6813            Slog.w(TAG, msg);
6814            throw new SecurityException(msg);
6815        }
6816        final int callingPid = Binder.getCallingPid();
6817        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
6818                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
6819        long callingId = Binder.clearCallingIdentity();
6820        try {
6821            IPackageManager pm = AppGlobals.getPackageManager();
6822            synchronized(this) {
6823                int[] users = userId == UserHandle.USER_ALL
6824                        ? mUserController.getUsers() : new int[] { userId };
6825                for (int user : users) {
6826                    if (getPackageManagerInternalLocked().isPackageStateProtected(
6827                            packageName, user)) {
6828                        Slog.w(TAG, "Ignoring request to force stop protected package "
6829                                + packageName + " u" + user);
6830                        return;
6831                    }
6832
6833                    int pkgUid = -1;
6834                    try {
6835                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6836                                user);
6837                    } catch (RemoteException e) {
6838                    }
6839                    if (pkgUid == -1) {
6840                        Slog.w(TAG, "Invalid packageName: " + packageName);
6841                        continue;
6842                    }
6843                    try {
6844                        pm.setPackageStoppedState(packageName, true, user);
6845                    } catch (RemoteException e) {
6846                    } catch (IllegalArgumentException e) {
6847                        Slog.w(TAG, "Failed trying to unstop package "
6848                                + packageName + ": " + e);
6849                    }
6850                    if (mUserController.isUserRunning(user, 0)) {
6851                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6852                        finishForceStopPackageLocked(packageName, pkgUid);
6853                    }
6854                }
6855            }
6856        } finally {
6857            Binder.restoreCallingIdentity(callingId);
6858        }
6859    }

里面调用到forceStopPackageLocked方法,

通过am命令force-stop 也可以调用forcestop,查看help信息,

am -hforce-stop [--user <USER_ID> | all | current] <PACKAGE>Completely stop the given application package.stop-app [--user <USER_ID> | all | current] <PACKAGE>Stop an app and all of its services.  Unlike `force-stop` this doesnot cancel the app's scheduled alarms and jobs.

注意看这个解释信息,如果不需要取消应用的scheduled alarms和jobs,可以使用stop-app

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@GuardedBy("this")
private void forceStopPackageLocked(final String packageName, int uid, String reason) {forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,false, true, false, false, UserHandle.getUserId(uid), reason);
}@GuardedBy("this")
final boolean forceStopPackageLocked(String packageName, int appId,boolean callerWillRestart, boolean purgeCache, boolean doit,boolean evenPersistent, boolean uninstalling, int userId, String reason) {int i;if (userId == UserHandle.USER_ALL && packageName == null) {Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");//不允许stop 所有用户的所有进程}if (appId < 0 && packageName != null) {try {appId = UserHandle.getAppId(AppGlobals.getPackageManager().getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));} catch (RemoteException e) {}}boolean didSomething;//当方法中有所行为,则返回true。只要杀过一个进程则代表didSomething为true.if (doit) {if (packageName != null) {Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId+ " user=" + userId + ": " + reason);//log打印,会打印出stop的reason} else {Slog.i(TAG, "Force stopping u" + userId + ": " + reason);}mAppErrors.resetProcessCrashTime(packageName == null, appId, userId);}synchronized (mProcLock) {// Notify first that the package is stopped, so its process won't be restarted// unexpectedly if there is an activity of the package without attached process// becomes visible when killing its other processes with visible activities.didSomething = mAtmInternal.onForceStopPackage(packageName, doit, evenPersistent, userId);//主要方法:强制停止该packagedidSomething |= mProcessList.killPackageProcessesLSP(packageName, appId, userId,ProcessList.INVALID_ADJ, callerWillRestart, false /* allowRestart */, doit,evenPersistent, true /* setRemoved */,packageName == null ? ApplicationExitInfo.REASON_USER_STOPPED: ApplicationExitInfo.REASON_USER_REQUESTED,ApplicationExitInfo.SUBREASON_UNKNOWN,(packageName == null ? ("stop user " + userId) : ("stop " + packageName))+ " due to " + reason);//主要方法:停止该pakcage所涉及的进程}if (mServices.bringDownDisabledPackageServicesLocked(packageName, null /* filterByClasses */, userId, evenPersistent, doit)) {//主要方法:清理该package所涉及的Serviceif (!doit) {return true;}didSomething = true;}if (packageName == null) {// Remove all sticky broadcasts from this user.mStickyBroadcasts.remove(userId);//删除粘性广播}ArrayList<ContentProviderRecord> providers = new ArrayList<>();if (mCpHelper.getProviderMap().collectPackageProvidersLocked(packageName, null, doit,evenPersistent, userId, providers)) {//收集该package相关的providerif (!doit) {return true;}didSomething = true;}for (i = providers.size() - 1; i >= 0; i--) {mCpHelper.removeDyingProviderLocked(null, providers.get(i), true);//主要方法:清理该package所涉及的Provider}// Remove transient permissions granted from/to this package/usermUgmInternal.removeUriPermissionsForPackage(packageName, userId, false, false);//主要方法:删除授予/授予此包/用户的临时权限if (doit) {for (i = mBroadcastQueues.length - 1; i >= 0; i--) {didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(packageName, null, userId, doit);//主要方法:清理该package所涉及的广播}}if (packageName == null || uninstallbringDownDisabledPackageServicesLockeding) {didSomething |= mPendingIntentController.removePendingIntentsForPackage(packageName, userId, appId, doit);//主要方法:移除所涉及到的intent}if (doit) {if (purgeCache && packageName != null) {AttributeCache ac = AttributeCache.instance();if (ac != null) {ac.removePackage(packageName);}}if (mBooted) {mAtmInternal.resumeTopActivities(true /* scheduleIdle */);}}return didSomething;
}

这里还有释放资源

很多年前,曾经遇到一个卸载应用导致的重启问题,就是因为卸载的时候,没有及时的执行

ac.removePackage(packageName)导致的。

参考资料:

基于Android 12的force-stop流程分析_android forcestop-CSDN博客


http://www.ppmy.cn/news/1556418.html

相关文章

Deveco Studio首次编译项目初始化失败

编译项目失败 Ohpm install失败的时候重新使用管理者打开程序 build init 初始化失败遇到了以下报错信息 Installing pnpm8.13.1... npm ERR! code CERT_HAS_EXPIRED npm ERR! errno CERT_HAS_EXPIRED npm ERR! request to https://registry.npm.taobao.org/pnpm failed, r…

按类别调整目标检测标注框的写入顺序以优化人工审核效率

引言 在目标检测数据标注审核过程中&#xff0c;我们常常会遇到以下情况&#xff1a;某些小目标的检测框嵌套在大目标检测框内&#xff0c;而在模型进行预标注后&#xff0c;这些小目标的框可能被写入到了大目标框的下层。在人工审核阶段&#xff0c;标注审核人员需要手动移动…

Mapper代理开发

引入 Mybatis入门方式中&#xff0c;以下代码仍存在硬编码问题 Mapper 代理开发&#xff1a; 目的&#xff1a; 解决原生方式中的硬编码 简化后期执行sql ------下图中&#xff0c;第一段代码是原生硬编码代码块&#xff0c;第二个是引入了Mapper代理开发的代码块。 Mapper代…

TCP Analysis Flags 之 TCP Fast Retransmission

前言 默认情况下&#xff0c;Wireshark 的 TCP 解析器会跟踪每个 TCP 会话的状态&#xff0c;并在检测到问题或潜在问题时提供额外的信息。在第一次打开捕获文件时&#xff0c;会对每个 TCP 数据包进行一次分析&#xff0c;数据包按照它们在数据包列表中出现的顺序进行处理。可…

1688商品爬取:商品信息与价格接口获取指南

引言 在电商领域&#xff0c;获取商品信息和价格对于市场分析、价格监控和供应链管理至关重要。1688作为中国领先的B2B电商平台&#xff0c;提供了海量的商品数据。本文将详细介绍如何利用Java爬虫技术合法合规地获取1688商品信息和价格接口数据。 环境准备 在开始之前&…

FPGA高速下载器SZ901

SZ901基于AMD(Xilinx) Virtual Cable协议. 本设备使用千兆网络接口。基于此接口,本设备可以同时支持多达四路FPGA板卡同时调试,每组相互独立,互不干扰。 特点 1,支持JTAG 速度最高53Mb/s&#xff0c;电压范围1.2-3.3V,最高支持200cm排线 2,支持4路JTAG独立使用 3,支持多路…

半导体制造全流程

半导体制造是一个极其复杂且精密的过程&#xff0c;主要涉及将硅片加工成功能强大的芯片。以下是半导体制造的全流程概述&#xff1a; 1. 硅材料制备 硅提纯&#xff1a; 使用冶金级硅&#xff0c;进一步提纯为高纯度硅&#xff08;电子级硅&#xff09;&#xff0c;纯度可达 …

MIT S6081 2024 Lab 1 | Operating System | Notes

目录 安装与下载 实验1 开始我们的实验 sleep&#xff08;简单&#xff09; pingpong&#xff08;简单&#xff09; primes (中等)/(困难) find&#xff08;中等&#xff09; xargs&#xff08;中等&#xff09; finally Reference I. Tools Debian 或 Ubuntu Arch…