[实践] Android源码 - 阻止APP被长按HOME键方式结束掉

[实践] Android源码 - 阻止APP被长按HOME键方式结束掉

@(Android研究)[阻止APP被系统结束]


[TOC]


前言

本文只讲做法,不讲理论。

实践

系统:Android5.1.1

当前实践修改了Android5.1.1的源码。

理论部分可以看我的文章:Android5.1.1源码 - 分析在最近的APP列表中清理APP的过程

假设APP包名为"com.a.b.c",让包名为"com.a.b.c"的APP进程不被系统结束掉。

找到ActivityManagerService.cleanUpRemovedTaskLocked方法所在的文件"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;
    }

    if (!killProcess) {
        return;
    }

    // Determine if the process(es) for this task should be killed.
    final String pkg = component.getPackageName();

    // 新添加的代码。
    if("com.a.b.c".equals(pkg)) {
        return;
    }

    ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
    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;
                }
            }

            // 除了不被删除的任务,剩下的任务都可以被结束。
            // Add process to kill list.
            procsToKill.add(proc);
        }
    }

    // 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";
        }
    }
}

下面是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;
    }

    if (!killProcess) {
        return;
    }

    // Determine if the process(es) for this task should be killed.
    final String pkg = component.getPackageName();
    ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
    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;
                }
            }

            // 除了不被删除的任务,剩下的任务都可以被结束。
            // Add process to kill list.
            procsToKill.add(proc);
        }
    }

    // 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";
        }
    }
}

实践二

系统:Android4.4.4_r2

当前实践修改了Android4.4.4_r2的源码。

找到ActivityManagerService.cleanUpRemovedTaskLocked方法所在的文件"frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java",下面是ActivityManagerService.cleanUpRemovedTaskLocked方法的源码:

private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
    tr.disposeThumbnail();
    mRecentTasks.remove(tr);
    final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
    Intent baseIntent = new Intent(
            tr.intent != null ? tr.intent : tr.affinityIntent);
    ComponentName component = baseIntent.getComponent();
    if (component == null) {
        Slog.w(TAG, "Now component for base intent of task: " + tr);
        return;
    }

    ......

    if (killProcesses) {
        ......
    }
}

通过观察上面的源码可以发现当killProcesses为true时将会执行清理代码,当killProcesses为false时则不会执行清理代码,而killProcesses是否为true与ActivityManager.REMOVE_TASK_KILL_PROCESS标志相关。

下面是对ActivityManagerService.cleanUpRemovedTaskLocked方法修改后的代码:

private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {

    flags = flags&ActivityManager.REMOVE_TASK_KILL_PROCESS;

    tr.disposeThumbnail();
    mRecentTasks.remove(tr);
    final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
    Intent baseIntent = new Intent(
            tr.intent != null ? tr.intent : tr.affinityIntent);
    ComponentName component = baseIntent.getComponent();
    if (component == null) {
        Slog.w(TAG, "Now component for base intent of task: " + tr);
        return;
    }

    ......

    if (killProcesses) {
        ......
    }
}

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值