关于Android的浅杀

android.app.ActivityManager类提供了removeTask方法来清理任务。
在API21及之前,removeTask中提供一个参数来指定是否要连同任务所运行的进程一起杀掉。
这个方法的第二个参数就是用来指定是否要连同进程一起杀掉,可以为0或者REMOVE_TASK_KILL_PROCESS。
我们先看在4.4上的实现:

    /**
     * Completely remove the given task.
     *
     * @param taskId Identifier of the task to be removed.
     * @param flags Additional operational flags.  May be 0 or
     * {@link #REMOVE_TASK_KILL_PROCESS}.
     * @return Returns true if the given task was found and removed.
     *
     * @hide
     */
    public boolean removeTask(int taskId, int flags)
            throws SecurityException {
        try {
            return ActivityManagerNative.getDefault().removeTask(taskId, flags);
        } catch (RemoteException e) {
            // System dead, we will be dead too soon!
            return false;
        }
    }

在ActivityManager中提供的只是一个接口,真正的实现要通过IPC去调用ActivityManagerService的removeTask. 主要的逻辑在cleanUpRemovedTaskLocked中实现。

    @Override
    public boolean removeTask(int taskId, int flags) {
...
            try {
                TaskRecord tr = recentTaskForIdLocked(taskId);
                if (tr != null) {
                    ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false);
                    if (r != null) {
                        cleanUpRemovedTaskLocked(tr, flags);
                        return true;
                    }
...
    }

我们再往下看cleanUpRemovedTaskLocked的逻辑,如果flags&ActivityManager.REMOVE_TASK_KILL_PROCESS就杀进程。

    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
...
        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;

...

        if (killProcesses) {
...
                    killUnneededProcessLocked(pr, "remove task");
                } else {
                    pr.waitingToKill = "remove task";
                }
            }
        }
    }

杀进程的逻辑在killUnneededProcessLocked中,接着调用android.os.Process.killProcessQuiet方法来杀进程。然后调用bionic中的函数来做系统调用。

    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
        if (!pr.killedByAm) {
            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
                    pr.processName, pr.setAdj, reason);
            pr.killedByAm = true;
            Process.killProcessQuiet(pr.pid);
        }
    }

比如ARM的kill调用是这样的:

ENTRY(kill)
    mov     ip, r7
    ldr     r7, =__NR_kill
    swi     #0
    mov     r7, ip
    cmn     r0, #(MAX_ERRNO + 1)
    bxls    lr
    neg     r0, r0
    b       __set_errno_internal
END(kill)

在AArch64状态下,swi已经失效了,替换成svc指令。

ENTRY(kill)
    mov     x8, __NR_kill
    svc     #0

    cmn     x0, #(MAX_ERRNO + 1)
    cneg    x0, x0, hi
    b.hi    __set_errno_internal

    ret
END(kill)

在Intel x86芯片上,系统调用要用int 0x80软中断。

ENTRY(kill)
    pushl   %ebx
    pushl   %ecx
    mov     12(%esp), %ebx
    mov     16(%esp), %ecx
    movl    $__NR_kill, %eax
    int     $0x80
    cmpl    $-MAX_ERRNO, %eax
    jb      1f
    negl    %eax
    pushl   %eax
    call    __set_errno
    addl    $4, %esp
    orl     $-1, %eax
1:
    popl    %ecx
    popl    %ebx
    ret
END(kill)

但是在x86_64指令集中,系统调用已经变成基本指令了,不再需要int 0x80了。

ENTRY(kill)
    movl    $__NR_kill, %eax
    syscall
    cmpq    $-MAX_ERRNO, %rax
    jb      1f
    negl    %eax
    movl    %eax, %edi
    call    __set_errno_internal
1:
    ret
END(kill)


从API 22开始,情况出现了一些变化,带参数的API被取消了,默认就杀进程。
我们看5.1的代码:

    /**
     * Completely remove the given task.
     *
     * @param taskId Identifier of the task to be removed.
     * @return Returns true if the given task was found and removed.
     *
     * @hide
     */
    public boolean removeTask(int taskId) throws SecurityException {
        try {
            return ActivityManagerNative.getDefault().removeTask(taskId);
        } catch (RemoteException e) {
            // System dead, we will be dead too soon!
            return false;
        }
    }

经过IPC,走到ActivityManagerService中,默认调用removeTaskByIdLocked时就杀进程。

    @Override
    public boolean removeTask(int taskId) {
        synchronized (this) {
            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
                    "removeTask()");
            long ident = Binder.clearCallingIdentity();
            try {
                return removeTaskByIdLocked(taskId, true);
            } finally {
                Binder.restoreCallingIdentity(ident);
            }
        }
    }

我们继续看removeTaskByIdLocked,还是会调用cleanUpRemovedTaskLocked,这两个方法都是可以控制是否要杀进程的。

    /**
     * Removes the task with the specified task id.
     *
     * @param taskId Identifier of the task to be removed.
     * @param killProcess Kill any process associated with the task if possible.
     * @return Returns true if the given task was found and removed.
     */
    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
        TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
        if (tr != null) {
            tr.removeTaskActivitiesLocked();
            cleanUpRemovedTaskLocked(tr, killProcess);
            if (tr.isPersistable) {
                notifyTaskPersisterLocked(null, true);
            }
            return true;
        }
        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
        return false;
    }
    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
        mRecentTasks.remove(tr);
        tr.removedFromRecents();

......

        if (!killProcess) {
            return;
        }
......
时间: 2024-09-17 04:17:48

关于Android的浅杀的相关文章

Android编程之杀毒的实现原理及具体实例

本文实例讲述了Android杀毒的实现原理.分享给大家供大家参考,具体如下: 一个杀毒软甲最核心的部分一个是病毒库一个是杀毒引擎,病毒库从服务器中获得,杀毒引擎实际上是判断程序中的包名和签名是否匹配病毒库中的包名和签名,如果匹配则为病毒,界面使用帧动画来显示. 思路: 1.从服务器端把病毒的版本库信息下载下来将解析的数据存放到List集合中 2.获取到手机中所有应用程序的包名以及程序的签名 3.将病毒库匹配手机应用程序包名及签名 4.用ScrollView标签进行自动滚动显示 关键代码如下: 特

Android杀毒软件查杀率对比评测

参测杀毒软件及测试方法在这个各类信息横飞的时代,守住个人隐私变得越来越困难,各种各样稀奇百怪的恶意软件无不觊觎着我们手机中的资料,因此对于Android手机来说一款防病毒软件是必不可少的.之前我们曾经做过此类软件后台待机运行的耗电量测试,今天我们来测试一下 它们的查杀率.本期参与测试的软件:360手机卫士评测版本 2.9.0 beta软件大小 4.3 MB系统需求 Android 2.1 及以上版本LBE安全大师评测版本 3.6.2039软件大小 2.03 MB系统需求 Android 2.0

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

Android中杀进程的几种方法 (1) - killBackgroundProcesses ActivityManager中提供了几种方式来杀进程,比如有forceStopPackage.removeTask.killBackgroundProcesses等. 下面我们就来看看它们的背后都做了些什么. removeTask 我们之前已经写了一篇<关于Android的浅杀>来介绍这个方法的变迁,大家可以回忆一下找找感觉. 复习一下removeTask的好处是,相对后面几个,它的逻辑要简单得多.

Andriod恶意代码分析与取证

根据CNNIC发布第36次<中国互联网络发展状况统计报告>,截至2015年6月,我国手机网民规模达5.94亿,较2014年12月增加3679万人,网民中使用手机上网的人群占比提升至88.9%,随着手机终端的大屏化和手机应用体验的不断提升,手机作为网民主要上网终端的趋势进一步明显,移动互联已成为这个时代的特征,同时Andriod与ios并肩成为目前主流的移动操作系统. Android是由google开发,基于Linux内核的开源手机操作系统.Android自面试以来,以其自由开放包容的姿态,迅速

I.MX6 Surfaceflinger 机制

/**************************************************************************** * I.MX6 Surfaceflinger 机制 * 说明: * 最近需要去分析一下Surfaceflinger工作机制,记录一下相关的文档和主要的 * 处理函数. * * 2016-9-14 深圳 南山平山村 曾剑锋 *************************************************************

蚕豆网精品APP推荐第316期:免费畅聊

每日看酷闻,当日新鲜IT资讯全Hold住,移动互联耍酷玩Fashion尽在蚕豆!欢迎订阅 蚕豆网.[产品资讯] iOS版<谷歌地图>更新 优化通讯录iOS版<谷歌地图>发布至今已3月有余,日前进行了第一次的更新.更新后的<谷歌地图>在三方面优化了自己的软件.搜索您的 Google 通讯录,在登录状态下,当您搜索亲朋好友的名字时系统 就会显示您保存的他们的地址.选择餐馆.酒吧.咖啡馆.加油站等热门类别,快速查找本地地点.选择您偏好的距离单位:公里或英里.[产品资讯] 迪斯

KDDI:日本运营商的“智能管道”尝试

即使在付费习惯很好的日本,如何通过移动互联网的内容产业赚钱,也是个让人头疼的问题.日本运营商过去的那套运营良好的运营商封闭体系受到了iPhone为代表的智能手机的巨大冲击.用户通过苹果的App Store和谷歌的Google Play就可以下载应用,不再需要通过运营商的渠道.为应对这种挑战,日本第二大运营商KDDI推出了一项名为SmartPass的套餐服务.用户每月只需要交399日元(在日本仅仅相当于坐一两次地铁的钱),即可以免费下载由KDDI打包买下的500多个手机App,此外,还能享受KDD

[Android 泥水匠] Android基础 之一:浅谈Android架构到HelloWorld案例的剖析

1.1前言   泥瓦匠又和大家见面了,在移动平台干过原生态开发,也干过hybrid应用.可以看看相关的文章 Android UI .所以多多少少在这块还是有点了解.现在很多高级语言可以开发app程序,包括Android,到我觉得目前Java语言开发Android程序还是很火,很重要的.自然,Java的底子不可少.可以看看泥瓦匠写的不少基础 Java Basic .   我们生活在一个通讯的时代,我经历过得2.5G时代,也就是GPRS等的时代,前面还有2G(GSM等).1G,后面则大家熟悉的3G

android 类qq空间图片查看器。出现好多错误 求大神帮忙。小女涉入甚浅。

问题描述 android 类qq空间图片查看器.出现好多错误 求大神帮忙.小女涉入甚浅. 11-20 11:26:39.629: E/AndroidRuntime(1136): FATAL EXCEPTION: main 11-20 11:26:39.629: E/AndroidRuntime(1136): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.desktop/co