Android中杀进程的几种方法 (1) - killBackgroundProcesses
2016-07-08 18:25
447 查看
Android中杀进程的几种方法 (1) - killBackgroundProcesses
ActivityManager中提供了几种方式来杀进程,比如有forceStopPackage、removeTask、killBackgroundProcesses等。下面我们就来看看它们的背后都做了些什么。
removeTask
我们之前已经写了一篇《关于Android的浅杀》来介绍这个方法的变迁,大家可以回忆一下找找感觉。复习一下removeTask的好处是,相对后面几个,它的逻辑要简单得多。
killBackgroundProcesses
ActivityManager中的killBackgroundProcesses
这是目前(截止至API24)唯一官方公开建议使用的方法,其它的都是隐藏的API。我们先看一张这个API背后调用的简图:
另外有一个被废弃的restartPackage方法,现在只是killBackgroundProcesses的马甲。
2400 @Deprecated 2401 public void restartPackage(String packageName) { 2402 killBackgroundProcesses(packageName); 2403 }
调用killBackgroundProcesses需要权限android.Manifest.permission.KILL_BACKGROUND_PROCESSES
按照惯例,这个方法肯定是通过IPC调用到AMS中:
2418 public void killBackgroundProcesses(String packageName) { 2419 try { 2420 ActivityManagerNative.getDefault().killBackgroundProcesses(packageName, 2421 UserHandle.myUserId()); 2422 } catch (RemoteException e) { 2423 } 2424 }
AMS中的killBackgroundProcesses
我们直接来看AMS中的killBackgroundProcesses:5202 @Override 5203 public void killBackgroundProcesses(final String packageName, int userId) {
首先就是检查KILL_BACKGROUND_PROCESSES的权限:
5204 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5205 != PackageManager.PERMISSION_GRANTED && 5206 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5207 != PackageManager.PERMISSION_GRANTED) { 5208 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5209 + Binder.getCallingPid() 5210 + ", uid=" + Binder.getCallingUid() 5211 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5212 Slog.w(TAG, msg); 5213 throw new SecurityException(msg); 5214 } 5215
下面正式开始干活:
5216 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5217 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5218 long callingId = Binder.clearCallingIdentity(); 5219 try { 5220 IPackageManager pm = AppGlobals.getPackageManager(); 5221 synchronized(this) { 5222 int appId = -1; 5223 try { 5224 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5225 } catch (RemoteException e) { 5226 } 5227 if (appId == -1) { 5228 Slog.w(TAG, "Invalid packageName: " + packageName); 5229 return; 5230 }
真正的逻辑都在killPackageProcessesLocked中。调用进来的时候只有包名和用户ID两个参数,但是killPackageProcessesLocked却搞出来9个参数。
5231 killPackageProcessesLocked(packageName, appId, userId, 5232 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5233 } 5234 } finally { 5235 Binder.restoreCallingIdentity(callingId); 5236 } 5237 }
AMS的killPackageProcessesLocked
5541 private final boolean killPackageProcessesLocked(String packageName, int appId, 5542 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5543 boolean doit, boolean evenPersistent, String reason) { 5544 ArrayList<ProcessRecord> procs = new ArrayList<>(); 5545 5546 // Remove all processes this package may have touched: all with the 5547 // same UID (except for the system or root user), and all whose name 5548 // matches the package name. 5549 final int NP = mProcessNames.getMap().size(); 5550 for (int ip=0; ip<NP; ip++) { 5551 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5552 final int NA = apps.size(); 5553 for (int ia=0; ia<NA; ia++) { 5554 ProcessRecord app = apps.valueAt(ia); 5555 if (app.persistent && !evenPersistent) { 5556 // we don't kill persistent processes 5557 continue; 5558 } 5559 if (app.removed) { 5560 if (doit) { 5561 procs.add(app); 5562 } 5563 continue; 5564 } 5565 5566 // Skip process if it doesn't meet our oom adj requirement. 5567 if (app.setAdj < minOomAdj) { 5568 continue; 5569 } 5570 5571 // If no package is specified, we call all processes under the 5572 // give user id. 5573 if (packageName == null) { 5574 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5575 continue; 5576 } 5577 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5578 continue; 5579 } 5580 // Package has been specified, we want to hit all processes 5581 // that match it. We need to qualify this by the processes 5582 // that are running under the specified app and user ID. 5583 } else { 5584 final boolean isDep = app.pkgDeps != null 5585 && app.pkgDeps.contains(packageName); 5586 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5587 continue; 5588 } 5589 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5590 continue; 5591 } 5592 if (!app.pkgList.containsKey(packageName) && !isDep) { 5593 continue; 5594 } 5595 } 5596 5597 // Process has passed all conditions, kill it! 5598 if (!doit) { 5599 return true; 5600 } 5601 app.removed = true; 5602 procs.add(app); 5603 } 5604 }
前面各种条件都准备好了之后,针对每一个proc去调用removeProcessLocked.
5606 int N = procs.size(); 5607 for (int i=0; i<N; i++) { 5608 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5609 } 5610 updateOomAdjLocked(); 5611 return N > 0; 5612 }
AMS之removeProcessLocked(4)
5916 private final boolean removeProcessLocked(ProcessRecord app, 5917 boolean callerWillRestart, boolean allowRestart, String reason) { 5918 final String name = app.processName; 5919 final int uid = app.uid; ...
下面再调用两个参数的removeProcessNameLocked.
5923 removeProcessNameLocked(name, uid); 5924 if (mHeavyWeightProcess == app) { 5925 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5926 mHeavyWeightProcess.userId, 0)); 5927 mHeavyWeightProcess = null; 5928 } 5929 boolean needRestart = false; 5930 if (app.pid > 0 && app.pid != MY_PID) { 5931 int pid = app.pid; 5932 synchronized (mPidsSelfLocked) { 5933 mPidsSelfLocked.remove(pid); 5934 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5935 } 5936 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5937 if (app.isolated) { 5938 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5939 } 5940 boolean willRestart = false; 5941 if (app.persistent && !app.isolated) { 5942 if (!callerWillRestart) { 5943 willRestart = true; 5944 } else { 5945 needRestart = true; 5946 } 5947 }
前面的该通知的都通知到了,终于可以正式开杀了。
5948 app.kill(reason, true); 5949 handleAppDiedLocked(app, willRestart, allowRestart); 5950 if (willRestart) { 5951 removeLruProcessLocked(app); 5952 addAppLocked(app.info, false, null /* ABI override */); 5953 } 5954 } else { 5955 mRemovedProcesses.add(app); 5956 } 5957 5958 return needRestart; 5959 }
ProcessRecord之kill
543 void kill(String reason, boolean noisy) { 544 if (!killedByAm) { 545 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "kill"); 546 if (noisy) { 547 Slog.i(TAG, "Killing " + toShortString() + " (adj " + setAdj + "): " + reason); 548 } 549 EventLog.writeEvent(EventLogTags.AM_KILL, userId, pid, processName, setAdj, reason); 550 Process.killProcessQuiet(pid); 551 Process.killProcessGroup(info.uid, pid); 552 if (!persistent) { 553 killed = true; 554 killedByAm = true; 555 } 556 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 557 } 558 }
Process之killProcessQuiet
非常省事儿,发给一个SIGNAL_KILL出去就是了。1068 public static final void killProcessQuiet(int pid) { 1069 sendSignalQuiet(pid, SIGNAL_KILL); 1070 }
Process之killProcessGroup
这个直接用native写的。public static final native int killProcessGroup(int uid, int pid);
android_util_Process.cpp之android_os_Process_killProcessGroup
JNI函数只是一个简单地对libprocessgroup中的killProcessGroup的封装1035jint android_os_Process_killProcessGroup(JNIEnv* env, jobject clazz, jint uid, jint pid) 1036{ 1037 return killProcessGroup(uid, pid, SIGKILL); 1038}
processgroup.cpp之killProcessGroup
这是我们的逻辑头一次走进/system/core/中,位于/system/core/libprocessgroup/processgroup.cpp252int killProcessGroup(uid_t uid, int initialPid, int signal) 253{ 254 int processes; 255 const int sleep_us = 5 * 1000; // 5ms 256 int64_t startTime = android::uptimeMillis(); 257 int retry = 40; 258 259 while ((processes = killProcessGroupOnce(uid, initialPid, signal)) > 0) { 260 SLOGV("killed %d processes for processgroup %d\n", processes, initialPid); 261 if (retry > 0) { 262 usleep(sleep_us); 263 --retry; 264 } else { 265 SLOGE("failed to kill %d processes for processgroup %d\n", 266 processes, initialPid); 267 break; 268 } 269 } 270 271 SLOGV("Killed process group uid %d pid %d in %" PRId64 "ms, %d procs remain", uid, initialPid, 272 android::uptimeMillis()-startTime, processes); 273 274 if (processes == 0) { 275 return removeProcessGroup(uid, initialPid); 276 } else { 277 return -1; 278 } 279}
killProcessGroupOnce
216static int killProcessGroupOnce(uid_t uid, int initialPid, int signal) 217{ 218 int processes = 0; 219 struct ctx ctx; 220 pid_t pid; 221 222 ctx.initialized = false; 223 224 while ((pid = getOneAppProcess(uid, initialPid, &ctx)) >= 0) { 225 processes++; 226 if (pid == 0) { 227 // Should never happen... but if it does, trying to kill this 228 // will boomerang right back and kill us! Let's not let that happen. 229 SLOGW("Yikes, we've been told to kill pid 0! How about we don't do that."); 230 continue; 231 } 232 if (pid != initialPid) { 233 // We want to be noisy about killing processes so we can understand 234 // what is going on in the log; however, don't be noisy about the base 235 // process, since that it something we always kill, and we have already 236 // logged elsewhere about killing it. 237 SLOGI("Killing pid %d in uid %d as part of process group %d", pid, uid, initialPid); 238 } 239 int ret = kill(pid, signal); 240 if (ret == -1) { 241 SLOGW("failed to kill pid %d: %s", pid, strerror(errno)); 242 } 243 } 244 245 if (ctx.initialized) { 246 close(ctx.fd); 247 } 248 249 return processes; 250}
getOneAppProcess
我们再跟一下这个有趣的函数:getOneAppProcess112static pid_t getOneAppProcess(uid_t uid, int appProcessPid, struct ctx *ctx) 113{ 114 if (!ctx->initialized) { 115 int ret = initCtx(uid, appProcessPid, ctx); 116 if (ret < 0) { 117 return ret; 118 } 119 } 120 121 char *eptr; 122 while ((eptr = (char *)memchr(ctx->buf_ptr, '\n', ctx->buf_len)) == NULL) { 123 int ret = refillBuffer(ctx); 124 if (ret == 0) { 125 return -ERANGE; 126 } 127 if (ret < 0) { 128 return ret; 129 } 130 } 131 132 *eptr = '\0'; 133 char *pid_eptr = NULL; 134 errno = 0; 135 long pid = strtol(ctx->buf_ptr, &pid_eptr, 10); 136 if (errno != 0) { 137 return -errno; 138 } 139 if (pid_eptr != eptr) { 140 return -EINVAL; 141 } 142 143 ctx->buf_len -= (eptr - ctx->buf_ptr) + 1; 144 ctx->buf_ptr = eptr + 1; 145 146 return (pid_t)pid; 147}
removeProcessGroup
回头我们再看看removeProcessGroup,还要把对应的目录删掉。149static int removeProcessGroup(uid_t uid, int pid) 150{ 151 int ret; 152 char path[PROCESSGROUP_MAX_PATH_LEN] = {0}; 153 154 convertUidPidToPath(path, sizeof(path), uid, pid); 155 ret = rmdir(path); 156 157 convertUidToPath(path, sizeof(path), uid); 158 rmdir(path); 159 160 return ret; 161}
AMS之removeProcessLocked(2)
5872 private final ProcessRecord removeProcessNameLocked(final String name, final int uid) { 5873 ProcessRecord old = mProcessNames.remove(name, uid); 5874 if (old != null) { 5875 old.uidRecord.numProcs--; 5876 if (old.uidRecord.numProcs == 0) { 5877 // No more processes using this uid, tell clients it is gone. 5878 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 5879 "No more processes in " + old.uidRecord); 5880 enqueueUidChangeLocked(old.uidRecord, true); 5881 mActiveUids.remove(uid); 5882 } 5883 old.uidRecord = null; 5884 } 5885 mIsolatedProcesses.remove(uid); 5886 return old; 5887 }
AMS之enqueueUidChangeLocked
18855 private final void enqueueUidChangeLocked(UidRecord uidRec, boolean gone) { 18856 if (uidRec.pendingChange == null) { 18857 if (mPendingUidChanges.size() == 0) { ... 18860 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_MSG).sendToTarget(); 18861 } 18862 final int NA = mAvailUidChanges.size(); 18863 if (NA > 0) { 18864 uidRec.pendingChange = mAvailUidChanges.remove(NA-1); ... 18867 } else { 18868 uidRec.pendingChange = new UidRecord.ChangeItem(); ... 18871 } 18872 uidRec.pendingChange.uidRecord = uidRec; 18873 uidRec.pendingChange.uid = uidRec.uid; 18874 mPendingUidChanges.add(uidRec.pendingChange); 18875 } 18876 uidRec.pendingChange.gone = gone; 18877 uidRec.pendingChange.processState = uidRec.setProcState; 18878 }
DISPATCH_UIDS_CHANGED_MSG消息在Handler中是如何处理的呢?我们查AMS中的UiHandler:
1611 case DISPATCH_UIDS_CHANGED_MSG: { 1612 dispatchUidsChanged(); 1613 } break;
AMS之dispatchUidsChanged
3787 private void dispatchUidsChanged() { 3788 int N; 3789 synchronized (this) { 3790 N = mPendingUidChanges.size(); 3791 if (mActiveUidChanges.length < N) { 3792 mActiveUidChanges = new UidRecord.ChangeItem ; 3793 } 3794 for (int i=0; i<N; i++) { 3795 final UidRecord.ChangeItem change = mPendingUidChanges.get(i); 3796 mActiveUidChanges[i] = change; 3797 change.uidRecord.pendingChange = null; 3798 change.uidRecord = null; 3799 } 3800 mPendingUidChanges.clear(); ... 3803 } 3804 3805 if (mLocalPowerManager != null) { 3806 for (int j=0; j<N; j++) { 3807 UidRecord.ChangeItem item = mActiveUidChanges[j]; 3808 if (item.gone) { 3809 mLocalPowerManager.uidGone(item.uid); 3810 } else { 3811 mLocalPowerManager.updateUidProcState(item.uid, item.processState); 3812 } 3813 } 3814 } 3815 3816 int i = mUidObservers.beginBroadcast(); 3817 while (i > 0) { 3818 i--; 3819 final IUidObserver observer = mUidObservers.getBroadcastItem(i); 3820 if (observer != null) { 3821 try { 3822 for (int j=0; j<N; j++) { 3823 UidRecord.ChangeItem item = mActiveUidChanges[j]; 3824 if (item.gone) { ... 3827 observer.onUidGone(item.uid); 3828 } else { ... 3832 observer.onUidStateChanged(item.uid, item.processState); 3833 } 3834 } 3835 } catch (RemoteException e) { 3836 } 3837 } 3838 } 3839 mUidObservers.finishBroadcast(); 3840 3841 synchronized (this) { 3842 for (int j=0; j<N; j++) { 3843 mAvailUidChanges.add(mActiveUidChanges[j]); 3844 } 3845 } 3846 }
AMS之handleAppDiedLocked
最后我们再看一下handleAppDiedLocked,杀了之后,埋的事情也还是要管的。4564 private final void handleAppDiedLocked(ProcessRecord app, 4565 boolean restarting, boolean allowRestart) { 4566 int pid = app.pid;
后面大家可以看到这个清理用了180多行的代码,而这还不是全部。
4567 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
mLruProcesses也是要清理的。
4568 if (!kept && !restarting) { 4569 removeLruProcessLocked(app); 4570 if (pid > 0) { 4571 ProcessList.remove(pid); 4572 } 4573 } 4574 4575 if (mProfileProc == app) { 4576 clearProfilerLocked(); 4577 }
每个Activity负责去做自己的清理,这部分暂时先不分析了,以后用到了再说。
4579 // Remove this application's activities from active lists. 4580 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4581 4582 app.activities.clear(); 4583 4584 if (app.instrumentationClass != null) { 4585 Slog.w(TAG, "Crash of app " + app.processName 4586 + " running instrumentation " + app.instrumentationClass); 4587 Bundle info = new Bundle(); 4588 info.putString("shortMsg", "Process crashed."); 4589 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4590 } 4591 4592 if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) { 4593 // If there was nothing to resume, and we are not already 4594 // restarting this process, but there is a visible activity that 4595 // is hosted by the process... then make sure all visible 4596 // activities are running, taking care of restarting this 4597 // process. 4598 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4599 } 4600 }
AMS之removeLruProcessLocked
不光remove LRU,如果没杀掉的话,这里还会再杀一次。2811 final void removeLruProcessLocked(ProcessRecord app) { 2812 int lrui = mLruProcesses.lastIndexOf(app); 2813 if (lrui >= 0) { 2814 if (!app.killed) { 2815 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2816 Process.killProcessQuiet(app.pid); 2817 killProcessGroup(app.info.uid, app.pid); 2818 } 2819 if (lrui <= mLruProcessActivityStart) { 2820 mLruProcessActivityStart--; 2821 } 2822 if (lrui <= mLruProcessServiceStart) { 2823 mLruProcessServiceStart--; 2824 } 2825 mLruProcesses.remove(lrui); 2826 } 2827 }
AMS之cleanUpApplicationRecordLocked
这段就不细解释了,原文贴出来的原因是希望大家都体会到,埋葬还有这么多事情要做的。15504 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 15505 boolean restarting, boolean allowRestart, int index) { 15506 if (index >= 0) { 15507 removeLruProcessLocked(app); 15508 ProcessList.remove(app.pid); 15509 } 15510 15511 mProcessesToGc.remove(app); 15512 mPendingPssProcesses.remove(app); 15513 15514 // Dismiss any open dialogs. 15515 if (app.crashDialog != null && !app.forceCrashReport) { 15516 app.crashDialog.dismiss(); 15517 app.crashDialog = null; 15518 } 15519 if (app.anrDialog != null) { 15520 app.anrDialog.dismiss(); 15521 app.anrDialog = null; 15522 } 15523 if (app.waitDialog != null) { 15524 app.waitDialog.dismiss(); 15525 app.waitDialog = null; 15526 } 15527 15528 app.crashing = false; 15529 app.notResponding = false; 15530 15531 app.resetPackageList(mProcessStats); 15532 app.unlinkDeathRecipient(); 15533 app.makeInactive(mProcessStats); 15534 app.waitingToKill = null; 15535 app.forcingToForeground = null; 15536 updateProcessForegroundLocked(app, false, false); 15537 app.foregroundActivities = false; 15538 app.hasShownUi = false; 15539 app.treatLikeActivity = false; 15540 app.hasAboveClient = false; 15541 app.hasClientActivities = false; 15542 15543 mServices.killServicesLocked(app, allowRestart); 15544 15545 boolean restart = false; 15546 15547 // Remove published content providers. 15548 for (int i = app.pubProviders.size() - 1; i >= 0; i--) { 15549 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 15550 final boolean always = app.bad || !allowRestart; 15551 boolean inLaunching = removeDyingProviderLocked(app, cpr, always); 15552 if ((inLaunching || always) && cpr.hasConnectionOrHandle()) { 15553 // We left the provider in the launching list, need to 15554 // restart it. 15555 restart = true; 15556 } 15557 15558 cpr.provider = null; 15559 cpr.proc = null; 15560 } 15561 app.pubProviders.clear(); 15562 15563 // Take care of any launching providers waiting for this process. 15564 if (cleanupAppInLaunchingProvidersLocked(app, false)) { 15565 restart = true; 15566 } 15567 15568 // Unregister from connected content providers. 15569 if (!app.conProviders.isEmpty()) { 15570 for (int i = app.conProviders.size() - 1; i >= 0; i--) { 15571 ContentProviderConnection conn = app.conProviders.get(i); 15572 conn.provider.connections.remove(conn); 15573 stopAssociationLocked(app.uid, app.processName, conn.provider.uid, 15574 conn.provider.name); 15575 } 15576 app.conProviders.clear(); 15577 } 15578 15579 // At this point there may be remaining entries in mLaunchingProviders 15580 // where we were the only one waiting, so they are no longer of use. 15581 // Look for these and clean up if found. 15582 // XXX Commented out for now. Trying to figure out a way to reproduce 15583 // the actual situation to identify what is actually going on. 15584 if (false) { 15585 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) { 15586 ContentProviderRecord cpr = mLaunchingProviders.get(i); 15587 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 15588 synchronized (cpr) { 15589 cpr.launchingApp = null; 15590 cpr.notifyAll(); 15591 } 15592 } 15593 } 15594 } 15595 15596 skipCurrentReceiverLocked(app); 15597 15598 // Unregister any receivers. 15599 for (int i = app.receivers.size() - 1; i >= 0; i--) { 15600 removeReceiverLocked(app.receivers.valueAt(i)); 15601 } 15602 app.receivers.clear(); 15603 15604 // If the app is undergoing backup, tell the backup manager about it 15605 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 15606 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App " 15607 + mBackupTarget.appInfo + " died during backup"); 15608 try { 15609 IBackupManager bm = IBackupManager.Stub.asInterface( 15610 ServiceManager.getService(Context.BACKUP_SERVICE)); 15611 bm.agentDisconnected(app.info.packageName); 15612 } catch (RemoteException e) { 15613 // can't happen; backup manager is local 15614 } 15615 } 15616 15617 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) { 15618 ProcessChangeItem item = mPendingProcessChanges.get(i); 15619 if (item.pid == app.pid) { 15620 mPendingProcessChanges.remove(i); 15621 mAvailProcessChanges.add(item); 15622 } 15623 } 15624 mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 15625 15626 // If the caller is restarting this app, then leave it in its 15627 // current lists and let the caller take care of it. 15628 if (restarting) { 15629 return false; 15630 } 15631 15632 if (!app.persistent || app.isolated) { 15633 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, 15634 "Removing non-persistent process during cleanup: " + app); 15635 removeProcessNameLocked(app.processName, app.uid); 15636 if (mHeavyWeightProcess == app) { 15637 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 15638 mHeavyWeightProcess.userId, 0)); 15639 mHeavyWeightProcess = null; 15640 } 15641 } else if (!app.removed) { 15642 // This app is persistent, so we need to keep its record around. 15643 // If it is not already on the pending app list, add it there 15644 // and start a new process for it. 15645 if (mPersistentStartingProcesses.indexOf(app) < 0) { 15646 mPersistentStartingProcesses.add(app); 15647 restart = true; 15648 } 15649 } 15650 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v( 15651 TAG_CLEANUP, "Clean-up removing on hold: " + app); 15652 mProcessesOnHold.remove(app); 15653 15654 if (app == mHomeProcess) { 15655 mHomeProcess = null; 15656 } 15657 if (app == mPreviousProcess) { 15658 mPreviousProcess = null; 15659 } 15660 15661 if (restart && !app.isolated) { 15662 // We have components that still need to be running in the 15663 // process, so re-launch it. 15664 if (index < 0) { 15665 ProcessList.remove(app.pid); 15666 } 15667 addProcessNameLocked(app); 15668 startProcessLocked(app, "restart", app.processName); 15669 return true; 15670 } else if (app.pid > 0 && app.pid != MY_PID) { 15671 // Goodbye! 15672 boolean removed; 15673 synchronized (mPidsSelfLocked) { 15674 mPidsSelfLocked.remove(app.pid); 15675 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 15676 } 15677 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 15678 if (app.isolated) { 15679 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 15680 } 15681 app.setPid(0); 15682 } 15683 return false; 15684 }
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories