根据这篇文章作的笔记
基于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 -h
force-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 does
not 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);//主要方法:强制停止该package
didSomething |= 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所涉及的Service
if (!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相关的provider
if (!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/user
mUgmInternal.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博客