1, 概述
在系统内存较低时就会杀死一些进程,最明显的在卸载一个apk之前会杀死该apk所在的进程。在PMS的deletePackageLI方法中会调用killApplication方法杀死进程。因此,本文以killApplication方法为例来论述杀死进程的过程。当然在android系统中,还有很多情况下会杀死进程,例如在很多异常的时候会直接杀死进程。Java层基本都是在AMS中通过Process的方法杀死进程的。
2, kill进程
ProcessRecord的kill方法如下,
void kill(String reason, boolean noisy) {
if (!killedByAm) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "kill");
if (noisy) {
Slog.i(TAG, "Killing " + toShortString() + " (adj " + setAdj + "): " + reason);
}
EventLog.writeEvent(EventLogTags.AM_KILL, userId, pid, processName, setAdj, reason);
Process.killProcessQuiet(pid);
Process.killProcessGroup(uid, pid);
if (!persistent) {
killed = true;
killedByAm = true;
}
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
直接调用Process的静态方法killProcessQuiet/ killProcessGroup
其实,在Process中,还有一个killProcess方法也可以杀死进程。
killProcess方法如下,
public static final void killProcess(int pid) {
sendSignal(pid, SIGNAL_KILL);
}
public static final native void sendSignal(int pid, int signal);
Java层的sendSignal方法对应着android_util_Process.cpp的android_os_Process_sendSignal方法
android_os_Process_sendSignal方法如下,
void android_os_Process_sendSignal(JNIEnv* env, jobject clazz, jint pid, jint sig)
{
if (pid > 0) {
ALOGI("Sending signal. PID: %" PRId32 " SIG: %" PRId32, pid, sig);
kill(pid, sig);
}
}
ProcessRecord的kill调用流程图如下,
android_util_Process.cpp的android_os_Process_sendSignalQuiet方法如下,
void android_os_Process_sendSignalQuiet(JNIEnv* env, jobject clazz, jint pid, jint sig)
{
if (pid > 0) {
kill(pid, sig);
}
}
由此可见, killProcess和killProcessQuiet方法都是通过JNI机制最后调用kill方法来实现的。
再来看killProcessGroup方法是如何调用的。
android_os_Process_killProcessGroup方法如下,
jint android_os_Process_killProcessGroup(JNIEnv* env, jobject clazz, jint uid, jint pid)
{
return killProcessGroup(uid, pid, SIGKILL);
}
processgroup.cpp中的killProcessGroup方法如下,
static int killProcessGroupOnce(uid_t uid, int initialPid, int signal)
{
int processes = 0;
struct ctx ctx;
pid_t pid;
ctx.initialized = false;
// 获取进程,逐个杀死
while ((pid = getOneAppProcess(uid, initialPid, &ctx)) >= 0) {
processes++;
if (pid == 0) {
// Should never happen... but if it does, trying to kill this
// will boomerang right back and kill us! Let's not let that happen.
SLOGW("Yikes, we've been told to kill pid 0! How about we don't do that.");
continue;
}
if (pid != initialPid) {
// We want to be noisy about killing processes so we can understand
// what is going on in the log; however, don't be noisy about the base
// process, since that it something we always kill, and we have already
// logged elsewhere about killing it.
SLOGI("Killing pid %d in uid %d as part of process group %d", pid, uid, initialPid);
}
int ret = kill(pid, signal); // 杀死进程
if (ret == -1) {
SLOGW("failed to kill pid %d: %s", pid, strerror(errno));
}
}
if (ctx.initialized) {
close(ctx.fd);
}
return processes;
}
所以,process的三个杀死进程的方法都是调用kill方法完成,该方法位于用户空间的Native层。
更为详细的细节在此就不论述了。