文档章节

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

i
 i不歪
发布于 2015/11/23 11:58
字数 731
阅读 99
收藏 0

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<ServiceRecord> services = new ArrayList<ServiceRecord>();
    ArrayMap<ComponentName, ServiceRecord> alls = getServices(tr.userId);
    for (int i=0; i<alls.size(); i++) {
        ServiceRecord sr = alls.valueAt(i);
        if (sr.packageName.equals(component.getPackageName())) {
            services.add(sr);
        }
    }

    // Take care of any running services associated with the app.
    for (int i=0; i<services.size(); i++) {
        ServiceRecord sr = services.get(i);
        if (sr.startRequested) {
            if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
                Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
                stopServiceLocked(sr);
            } else {
                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);
                }
            }
        }
    }
}

这个方法先获得了所有的服务,然后将包名与"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标识,下面是一个例子:

<service android:stopWithTask="true" android:name=".MyService" android:process=":myservice" />

回到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方法重启服务。

© 著作权归作者所有

i
粉丝 5
博文 82
码字总数 71961
作品 0
西城
私信 提问
Android5.1.1源码 - App进程被杀后与App相关的所有服务进程均被杀的原因

Android5.1.1源码 - App进程被杀后与App相关的所有服务进程均被杀的原因 @(Android研究)[App服务进程被杀] [TOC] 前言 当通过清理一个App时,不仅这个App进程会被杀掉,与这个App相关的所有服...

i不歪
2015/11/23
57
0
android 4.x 如何开机启动进程,并保证服务不被杀死,并重启进程

我还是一只菜鸟,最近要做一个闹钟功能和推送功能,被要求开机自动启动服务,并能保证服务被杀死后能自动重启。 但遇到了不少问题,主要是4.x系统上: 是开机自动启动,在小米4.2系统上开发失...

Jack-X
2014/06/18
1K
6
不歪 - 自定义ROM文章索引贴

不歪 - 自定义ROM文章索引贴 @(Android研究)[自定义ROM] [TOC] 不歪博客:http://my.oschina.net/ibuwai/blog 前言 我为了方便逆向分析自定义了一个ROM,下面是自定义ROM过程中写的技术分享文...

i不歪
2016/07/28
117
0
应用保活终极总结(二):Android6.0及以上的保活实践(进程防杀篇)

原作者:“裂缝中的阳光dg”,本文现已重新修订并整理发布,感谢原作者的无私分享。 1、前言 在Android 4.4及以后的系统中,应用能否常驻内存,一直以来都是相当头疼的事情,尤其移动端IM、消...

JackJiang2011
2017/10/20
0
0
2018年Android的保活方案效果统计

一、常见保活方案 1、监听广播:监听全局的静态广播,比如时间更新的广播、开机广播、解锁屏、网络状态、解锁加锁亮屏暗屏(3.1版本),高版本需要应用开机后运行一次才能监听这些系统广播,...

codeGoogle
2018/10/30
0
0

没有更多内容

加载失败,请刷新页面

加载更多

哪些情况下适合使用云服务器?

我们一直在说云服务器价格适中,具备弹性扩展机制,适合部署中小规模的网站或应用。那么云服务器到底适用于哪些情况呢?如果您需要经常原始计算能力,那么使用独立服务器就能满足需求,因为他...

云漫网络Ruan
今天
9
0
Java 中的 String 有没有长度限制

转载: https://juejin.im/post/5d53653f5188257315539f9a String是Java中很重要的一个数据类型,除了基本数据类型以外,String是被使用的最广泛的了,但是,关于String,其实还是有很多东西...

低至一折起
今天
17
0
OpenStack 简介和几种安装方式总结

OpenStack :是一个由NASA和Rackspace合作研发并发起的,以Apache许可证授权的自由软件和开放源代码项目。项目目标是提供实施简单、可大规模扩展、丰富、标准统一的云计算管理平台。OpenSta...

小海bug
昨天
11
0
DDD(五)

1、引言 之前学习了解了DDD中实体这一概念,那么接下来需要了解的就是值对象、唯一标识。值对象,值就是数字1、2、3,字符串“1”,“2”,“3”,值时对象的特征,对象是一个事物的具体描述...

MrYuZixian
昨天
9
0
解决Mac下VSCode打开zsh乱码

1.乱码问题 iTerm2终端使用Zsh,并且配置Zsh主题,该主题主题需要安装字体来支持箭头效果,在iTerm2中设置这个字体,但是VSCode里这个箭头还是显示乱码。 iTerm2展示如下: VSCode展示如下: 2...

HelloDeveloper
昨天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部