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

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

removeTask

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

killBackgroundProcesses

ActivityManager中的killBackgroundProcesses

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

另外有一个被废弃的restartPackage方法,现在只是killBackgroundProcesses的马甲。

2400    @Deprecated2401    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    @Override5203    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<>();55455546        // Remove all processes this package may have touched: all with the5547        // same UID (except for the system or root user), and all whose name5548        // 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 processes5557                    continue;5558                }5559                if (app.removed) {5560                    if (doit) {5561                        procs.add(app);5562                    }5563                    continue;5564                }55655566                // Skip process if it doesn't meet our oom adj requirement.5567                if (app.setAdj < minOomAdj) {5568                    continue;5569                }55705571                // If no package is specified, we call all processes under the5572                // 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 processes5581                // that match it.  We need to qualify this by the processes5582                // that are running under the specified app and user ID.5583                } else {5584                    final boolean isDep = app.pkgDeps != null5585                            && 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                }55965597                // 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        }59575958        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;  // 5ms256    int64_t startTime = android::uptimeMillis();257    int retry = 40;258259    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    }270271    SLOGV("Killed process group uid %d pid %d in %" PRId64 "ms, %d procs remain", uid, initialPid,272            android::uptimeMillis()-startTime, processes);273274    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;221222    ctx.initialized = false;223224    while ((pid = getOneAppProcess(uid, initialPid, &ctx)) >= 0) {225        processes++;226        if (pid == 0) {227            // Should never happen...  but if it does, trying to kill this228            // 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 understand234            // what is going on in the log; however, don't be noisy about the base235            // process, since that it something we always kill, and we have already236            // 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    }244245    if (ctx.initialized) {246        close(ctx.fd);247    }248249    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    }120121    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    }131132    *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    }142143    ctx->buf_len -= (eptr - ctx->buf_ptr) + 1;144    ctx->buf_ptr = eptr + 1;145146    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};153154    convertUidPidToPath(path, sizeof(path), uid, pid);155    ret = rmdir(path);156157    convertUidToPath(path, sizeof(path), uid);158    rmdir(path);159160    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        }38043805        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        }38153816        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();38403841        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        }45744575        if (mProfileProc == app) {4576            clearProfilerLocked();4577        }

每个Activity负责去做自己的清理,这部分暂时先不分析了,以后用到了再说。

4579        // Remove this application's activities from active lists.4580        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);45814582        app.activities.clear();45834584        if (app.instrumentationClass != null) {4585            Slog.w(TAG, "Crash of app " + app.processName4586                  + " running instrumentation " + app.instrumentationClass);4587            Bundle info = new Bundle();4588            info.putString("shortMsg", "Process crashed.");4589            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);4590        }45914592        if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {4593            // If there was nothing to resume, and we are not already4594            // restarting this process, but there is a visible activity that4595            // is hosted by the process...  then make sure all visible4596            // activities are running, taking care of restarting this4597            // 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        }1551015511        mProcessesToGc.remove(app);15512        mPendingPssProcesses.remove(app);1551315514        // 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        }1552715528        app.crashing = false;15529        app.notResponding = false;1553015531        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;1554215543        mServices.killServicesLocked(app, allowRestart);1554415545        boolean restart = false;1554615547        // 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 to15554                // restart it.15555                restart = true;15556            }1555715558            cpr.provider = null;15559            cpr.proc = null;15560        }15561        app.pubProviders.clear();1556215563        // Take care of any launching providers waiting for this process.15564        if (cleanupAppInLaunchingProvidersLocked(app, false)) {15565            restart = true;15566        }1556715568        // 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        }1557815579        // At this point there may be remaining entries in mLaunchingProviders15580        // 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 reproduce15583        // 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        }1559515596        skipCurrentReceiverLocked(app);1559715598        // 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();1560315604        // If the app is undergoing backup, tell the backup manager about it15605        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 local15614            }15615        }1561615617        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();1562515626        // If the caller is restarting this app, then leave it in its15627        // current lists and let the caller take care of it.15628        if (restarting) {15629            return false;15630        }1563115632        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 there15644            // 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);1565315654        if (app == mHomeProcess) {15655            mHomeProcess = null;15656        }15657        if (app == mPreviousProcess) {15658            mPreviousProcess = null;15659        }1566015661        if (restart && !app.isolated) {15662            // We have components that still need to be running in the15663            // 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    }

更多相关文章

  1. Android客户端和服务器端数据交互的第四种方法
  2. Android选项卡的几种实现方法
  3. MTK 添加宏控方法
  4. Android AsyncTask onProgressUpdate 方法的些许研究
  5. Android Studio中genymotion安装方法
  6. Android使用HttpClient方法和易错问题
  7. Android开机自启动程序设置及控制方法思路浅谈
  8. android获取当前运行Activity名字的方法
  9. 将system_server进程配置成Android Application进程

随机推荐

  1. 更改.android目录位置
  2. 有关Android线程的学习
  3. 获取Android(安卓)SDK 源代码并在Eclipse
  4. Android(安卓)TextView属性详解
  5. android:windowSoftInputMode 介绍
  6. android的surfaceflinger原理讲解
  7. 【Android】 保存图片到系统图库, 并立即
  8. Android到Androidx记录
  9. Android开发规范:API接口通用设计规范
  10. EditText单击触发onclick事件处理