安卓或linux的机制是某个进程被杀死之后,它所在的进程组的所有进程都会被杀掉,但有时候客户需要保活它的子进程,按常规的流程无法实现,下面是一种思路方案:
1.当我们点recent键删除app的时候,走下面的流程:
frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java
removeStack->
removeTaskByIdLocked - >
private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
boolean removeFromRecents) {
if (removeFromRecents) { //判断从reecnt移除
mRecentTasks.remove(tr);
tr.removedFromRecents();
}
ComponentName component = tr.getBaseIntent().getComponent();
Log.i("fan","component name ="+component);
/* if(component.getPackageName().contains("msetpStudentSuite")){
Log.i("fan","not need kill master process");
return;
}*/
if (component == null) {
Slog.w(TAG, "No component for base intent of task: " + tr);
return;
}
// Find any running services associated with this app and stop if needed.
mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
if (!killProcess) {
return;
}
// Determine if the process(es) for this task should be killed.
final String pkg = component.getPackageName();
ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
for (int i = 0; i < pmap.size(); i++) {
SparseArray<ProcessRecord> uids = pmap.valueAt(i);
for (int j = 0; j < uids.size(); j++) {
ProcessRecord proc = uids.valueAt(j);
if (proc.userId != tr.userId) {
// Don't kill process for a different user.
continue;
}
if (proc == mHomeProcess) {
// Don't kill the home process along with tasks from the same package.
continue;
}
if (!proc.pkgList.containsKey(pkg)) {
// Don't kill process that is not associated with this task.
continue;
}
for (int k = 0; k < proc.activities.size(); k++) {
TaskRecord otherTask = proc.activities.get(k).task;
if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
// Don't kill process(es) that has an activity in a different task that is
// also in recents.
return;
}
}
if (proc.foregroundServices) {
// Don't kill process(es) with foreground service.
return;
}
if(component.getPackageName().contains("msetpStudentSuite")){ //这里根据包名获取进程的pid,保存到全局变量
Log.i("fan","process pid is"+proc.pid);
specialpid = proc.pid;
}
// Add process to kill list.
procsToKill.add(proc);
}
}
// Kill the running processes.
for (int i = 0; i < procsToKill.size(); i++) {
ProcessRecord pr = procsToKill.get(i);
if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
&& pr.curReceiver == null) {
pr.kill("remove task", true); //这里开始真正移除要删除的app进程
} else {
// We delay killing processes that are not in the background or running a receiver.
pr.waitingToKill = "remove task";
}
}
}
frameworks/base/services/core/java/com/android/server/am/ProcessRecord.java
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);
ActivityManagerService.killProcessGroup(uid, pid); //通过这个来杀死进程组所有的进程,子进程
if (!persistent) {
killed = true;
killedByAm = true;
}
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
最后就到了这里
\frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java
static void killProcessGroup(int uid, int pid) {
Log.d("fan","killProcessGroup");
Log.d("fan",Log.getStackTraceString(new Throwable()));
if(specialpid==pid){ //根据前面的id退出要杀的子进程
Log.i("fan","find special pid is"+pid);
return;
}
if (sKillHandler != null) {
sKillHandler.sendMessage(
sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
} else {
Slog.w(TAG, "Asked to kill process group before system bringup!");
Process.killProcessGroup(uid, pid);
}
}