Android中杀进程的几种方法 (1) - killBackgroundProcesses

Android中杀进程的几种方法 (1) - killBackgroundProcesses

ActivityManager中提供了几种方式来杀进程,比如有forceStopPackage、removeTask、killBackgroundProcesses等。
下面我们就来看看它们的背后都做了些什么。

removeTask

我们之前已经写了一篇《关于Android的浅杀》来介绍这个方法的变迁,大家可以回忆一下找找感觉。
复习一下removeTask的好处是,相对后面几个,它的逻辑要简单得多。

killBackgroundProcesses

ActivityManager中的killBackgroundProcesses

这是目前(截止至API24)唯一官方公开建议使用的方法,其它的都是隐藏的API。
我们先看一张这个API背后调用的简图:
Android中杀进程的几种方法 (1) - killBackgroundProcesses_第1张图片

另外有一个被废弃的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 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; ip5551            SparseArray apps = mProcessNames.getMap().valueAt(ip);
5552            final int NA = apps.size();
5553            for (int ia=0; ia5554                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; i5608            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.cpp

252int 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

我们再跟一下这个有趣的函数:getOneAppProcess

112static 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[N];
3793            }
3794            for (int i=0; i3795                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; j3807                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; j3823                        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; j3843                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    }

你可能感兴趣的:(学习笔记)