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

简介: ActivityManager的killBackgroundProcesses背后的故事

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

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

removeTask

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

killBackgroundProcesses

ActivityManager中的killBackgroundProcesses

这是目前(截止至API24)唯一官方公开建议使用的方法,其它的都是隐藏的API。
我们先看一张这个API背后调用的简图:
killBackgroundProcesses

另外有一个被废弃的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.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; 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    }
目录
相关文章
|
3月前
|
存储 Shell Android开发
基于Android P,自定义Android开机动画的方法
本文详细介绍了基于Android P系统自定义开机动画的步骤,包括动画文件结构、脚本编写、ZIP打包方法以及如何将自定义动画集成到AOSP源码中。
76 2
基于Android P,自定义Android开机动画的方法
|
3月前
|
Android开发
基于android-11.0.0_r39,系统应用的手动签名方法和过程
本文介绍了基于Android 11.0.0_r39版本进行系统应用手动签名的方法和解决签名过程中遇到的错误,包括处理`no conscrypt_openjdk_jni-linux-x86_64`和`RegisterNatives failed`的问题。
182 2
|
22天前
|
缓存 Java Shell
Android 系统缓存扫描与清理方法分析
Android 系统缓存从原理探索到实现。
46 15
Android 系统缓存扫描与清理方法分析
|
23天前
|
运维 Linux
Linux查找占用的端口,并杀死进程的简单方法
通过上述步骤和命令,您能够迅速识别并根据实际情况管理Linux系统中占用特定端口的进程。为了获得更全面的服务器管理技巧和解决方案,提供了丰富的资源和专业服务,是您提升运维技能的理想选择。
25 1
|
2月前
|
ARouter 测试技术 API
Android经典面试题之组件化原理、优缺点、实现方法?
本文介绍了组件化在Android开发中的应用,详细阐述了其原理、优缺点及实现方式,包括模块化、接口编程、依赖注入、路由机制等内容,并提供了具体代码示例。
45 2
|
2月前
|
存储 监控
【Azure Cloud Service】在Azure云服务中收集CPU监控指标和IIS进程的DUMP方法
在使用Cloud Service服务时,发现服务的CPU占用很高,在业务请求并不大的情况下,需要直到到底是什么进程占用了大量的CPU资源,已经如何获取IIS进程(w3wp.exe)的DUMP文件?
|
2月前
|
Java Android开发 数据安全/隐私保护
Android中多进程通信有几种方式?需要注意哪些问题?
本文介绍了Android中的多进程通信(IPC),探讨了IPC的重要性及其实现方式,如Intent、Binder、AIDL等,并通过一个使用Binder机制的示例详细说明了其实现过程。
312 4
|
2月前
|
编译器
【收藏】内核级利用通用Hook函数方法检测进程
【收藏】内核级利用通用Hook函数方法检测进程
|
3月前
|
API Android开发
Android P 性能优化:创建APP进程白名单,杀死白名单之外的进程
本文介绍了在Android P系统中通过创建应用进程白名单并杀死白名单之外的进程来优化性能的方法,包括设置权限、获取运行中的APP列表、配置白名单以及在应用启动时杀死非白名单进程的代码实现。
62 1
|
3月前
|
Android开发
Android在rootdir根目录创建自定义目录和挂载点的方法
本文介绍了在Android高通平台的根目录下创建自定义目录和挂载点的方法,通过修改Android.mk文件并使用`LOCAL_POST_INSTALL_CMD`变量在编译过程中添加目录,最终在ramdisk.img的系统根路径下成功创建了`/factory/bin`目录。
207 1

相关实验场景

更多