根据这篇文章作的笔记
基于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博客