Android5.1.1源码 - App服务进程被杀后自动重启的原因

为什么80%的码农都做不了架构师?>>>   hot3.png

Android5.1.1源码 - App服务进程被杀后自动重启的原因

@(Android研究)[App服务重启]


[TOC]


前言

当通过长按HOME键的方式清理一个App时,不仅这个App进程会被杀掉,与这个App相关的服务进程也会被杀掉,但是服务进程被杀后会被系统重启,在下文中分析了重启的原因。

分析

长按HOME键清理App最终会执行到ActivityManagerService.cleanUpRemovedTaskLocked方法中,ActivityManagerService类在文件"frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java"中,下面是ActivityManagerService.cleanUpRemovedTaskLocked方法的源码:

private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
    mRecentTasks.remove(tr);
    tr.removedFromRecents();
    ComponentName component = tr.getBaseIntent().getComponent();
    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()));

    // Kill the running processes.
    for (int i = 0; i < procsToKill.size(); i++) {
        ProcessRecord pr = procsToKill.get(i);
        if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
            pr.kill("remove task", true);
        } else {
            pr.waitingToKill = "remove task";
        }
    }
}

mServices是ActiveServices类的对象,mServices.cleanUpRemovedTaskLocked(...)语句杀掉了与app相关的服务进程,在执行完ActiveServices.cleanUpRemovedTaskLocked方法后,就会调用pr.kill方法杀掉app进程和app所属进程组中所有的进程。关于杀掉app所属进程组所有进程的分析可以看这篇文章:Android5.1.1源码 - App进程被杀后与App相关的所有服务进程均被杀的原因。本文主要分析ActiveServices.cleanUpRemovedTaskLocked方法做了什么。

ActiveServices类的源码在文件"frameworks/base/services/core/java/com/android/server/am/ActiveServices.java"中,下面是ActiveServices.cleanUpRemovedTaskLocked方法的源码:

void cleanUpRemovedTaskLocked(TaskRecord tr, ComponentName component, Intent baseIntent) {
    ArrayList services = new ArrayList();
    ArrayMap alls = getServices(tr.userId);
    for (int i=0; i

这个方法先获得了所有的服务,然后将包名与"component.getPackageName()"相等的服务保存到了services中。

遍历services,sr.startRequested为true表明这个服务已经启动,当sr.serviceInfo.flags设置了ServiceInfo.FLAG_STOP_WITH_TASK标识时,会调用stopServiceLocked方法停止服务,如果调用了stopServiceLocked方法那么这个服务就不会再重启了

什么情况下会设置ServiceInfo.FLAG_STOP_WITH_TASK标识哪?当App的AndroidManifest.xml中服务标签被设置了android:stopWithTask="true",那么sr.serviceInfo.flags会被设置ServiceInfo.FLAG_STOP_WITH_TASK标识,下面是一个例子:


回到ActiveServices.cleanUpRemovedTaskLocked方法中,当sr.serviceInfo.flags没有设置ServiceInfo.FLAG_STOP_WITH_TASK标识时,会执行下面的代码:

sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
        sr.makeNextStartId(), baseIntent, null));
if (sr.app != null && sr.app.thread != null) {
    // We always run in the foreground, since this is called as
    // part of the "remove task" UI operation.
    sendServiceArgsLocked(sr, true, false);
}

sr.pendingStarts.add(...)语句添加了要重启的服务信息,然后调用sendServiceArgsLocked方法重启服务。

转载于:https://my.oschina.net/ibuwai/blog/534157

你可能感兴趣的:(Android5.1.1源码 - App服务进程被杀后自动重启的原因)