removeTask

SystemUI中,Home键调出小刷子杀最近任务,整个流程从其RecentsPanelView.java开始:

public void handleSwipe(View view) {
...
// Currently, either direction means the same thing, so ignore direction and remove
        // the task.
        final ActivityManager am = (ActivityManager)
                getContext().getSystemService(Context.ACTIVITY_SERVICE);
        if (am != null) {
            am.removeTask(ad.persistentTaskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);①
            // Accessibility feedback
            setContentDescription(
                    getContext().getString(R.string.accessibility_recents_item_dismissed, ad.getLabel()));
            sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
            setContentDescription(null);
        }
}

ActivityManagerService.java

private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
        mRecentTasks.remove(tr);
        tr.removedFromRecents(mTaskPersister);
        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;
        }
        // Find any running services associated with this app.
        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);④
        if (killProcesses) {
            // Find any running processes associated with this app.
            final String pkg = component.getPackageName();
            ArrayList<ProcessRecord> procs = 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) {
                        continue;
                    }
                    if (!proc.pkgList.containsKey(pkg)) {
                        continue;
                    }
                    procs.add(proc);
                }
            }
            // Kill the running processes.
            for (int i=0; i<procs.size(); i++) {
                ProcessRecord pr = procs.get(i);
                if (pr == mHomeProcess) {
                    // Don‘t kill the home process along with tasks from the same package.
                    continue;
                }
                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
                    pr.kill("remove task", true);
                } else {
                    pr.waitingToKill = "remove task";
                }
            }
        }
    }
/**
     * Removes the task with the specified task id.
     *
     * @param taskId Identifier of the task to be removed.
     * @param flags Additional operational flags.  May be 0 or
     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
     * @return Returns true if the given task was found and removed.
     */
    private boolean removeTaskByIdLocked(int taskId, int flags) {
        TaskRecord tr = recentTaskForIdLocked(taskId);
        if (tr != null) {
            tr.removeTaskActivitiesLocked();
            cleanUpRemovedTaskLocked(tr, flags);③
            if (tr.isPersistable) {
                notifyTaskPersisterLocked(null, true);
            }
            return true;
        }
        return false;
    }
    @Override
    public boolean removeTask(int taskId, int flags) {
        synchronized (this) {
            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
                    "removeTask()");
            long ident = Binder.clearCallingIdentity();
            try {
                return removeTaskByIdLocked(taskId, flags);②
            } finally {
                Binder.restoreCallingIdentity(ident);
            }
        }
    }

ActiveServices.java

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);
                    }
                }
            }
        }
    }

TaskRecord.java

/**
     * Completely remove all activities associated with an existing
     * task starting at a specified index.
     */
    final void performClearTaskAtIndexLocked(int activityNdx) {
        int numActivities = mActivities.size();
        for ( ; activityNdx < numActivities; ++activityNdx) {
            final ActivityRecord r = mActivities.get(activityNdx);
            if (r.finishing) {
                continue;
            }
            if (stack == null) {
                // Task was restored from persistent storage.
                r.takeFromHistory();
                mActivities.remove(activityNdx);
                --activityNdx;
                --numActivities;
            } else if (stack.finishActivityLocked(r, Activity.RESULT_CANCELED, null, "clear",
                    false)) {
                --activityNdx;
                --numActivities;
            }
        }
    }
    /**
     * Completely remove all activities associated with an existing task.
     */
    final void performClearTaskLocked() {
        mReuseTask = true;
        performClearTaskAtIndexLocked(0);
        mReuseTask = false;
    }

Process.java

/**
     * Background thread group - All threads in
     * this group are scheduled with a reduced share of the CPU.
     * Value is same as constant SP_BACKGROUND of enum SchedPolicy.
     * FIXME rename to THREAD_GROUP_BACKGROUND.
     * @hide
     */
    public static final int THREAD_GROUP_BG_NONINTERACTIVE = 0;
时间: 2025-01-05 06:11:30

removeTask的相关文章

浅谈Android多屏幕的事

浅谈Android多屏幕的事 一部手机可以同时看片.聊天,还可以腾出一支手来撸!这么吊的功能(非N版本,非第三方也能实现,你不知道吧)摆在你面前,你不享用?不关注它是怎样实现的?你来,我就满足你的欲望! 一部手机可以同时看片.聊天,还可以腾出一支手来撸==!就像这样: 是时候告别来回切换应用屏幕的酸爽了,还可以在分屏模式下两Activity间直接拖放数据! 好高大上的样子!这是怎么实现的?别急,我们一一道来: kitkat(4.4)版本对多任务分屏的实现 由于相关的代码和功能被封装及隐藏起来,所

zone.js - 暴力之美

在ng2的开发过程中,Angular团队为我们带来了一个新的库 – zone.js.zone.js的设计灵感来源于Dart语言,它描述JavaScript执行过程的上下文,可以在异步任务之间进行持久性传递,它类似于Java中的TLS(thread-local storage: 线程本地存储)技术,zone.js则是将TLS引入到JavaScript语言中的实现框架. 那么zone.js能为我们解决什么问题呢?在回答这个问题之前,博主更希望回顾下在JavaScript开发中,我们究竟遇见了什么难题

ActivityManager

android.app.ActivityManager 这个类主要用来管理全部设备上的Activities. 权限:android.permission.GET_TASKS 方法:| 返回类型     方法| 1.List<ActivityManager.RecentTaskInfo>       getRecentTasks(int maxNum, int flags) 返回用户近期使用过的应用程序信息集合.第一个參数是最大数量,第二个參数在API11前仅仅有ActivityManager.

Netty源码阅读(一) ServerBootstrap启动

Netty源码阅读(一) ServerBootstrap启动 转自我的Github Netty是由JBOSS提供的一个java开源框架.Netty提供异步的.事件驱动的网络应用程序框架和工具,用以快速开发高性能.高可靠性的网络服务器和客户端程序.本文讲会对Netty服务启动的过程进行分析,主要关注启动的调用过程,从这里面进一步理解Netty的线程模型,以及Reactor模式. 这是我画的一个Netty启动过程中使用到的主要的类的概要类图,当然是用到的类比这个多得多,而且我也忽略了各个类的继承关系

阿里云自定义监控tomcat进程数

阿里云提供自定义监控SDK,这有助于我们定制化的根据自身业务来做监控,下面我就根据业务需求来介绍一个简单的自定义监控配置. 阿里提供了2个版本的自定义监控接口:自定义监控SDK(python版) :cms_post.py自定义监控SDK(bash版) :cms_post.sh下载地址:http://help.aliyun.com/knowledge_detail.htm?knowledgeId=5974901 本文使用shell版本做演示       这里说下我的简单需求,我们需要监控ECS服务

C3P0整体类结构简单分析

直接进入主题吧: 这张图只是C3P0的部分结构类图,不急,先对总体上有一个了解. 首先我们需要了解,C3P0是"懒初始化"的.也就是说它并不会自己初始化,而是会等到第一个连接请求进来之后它才会初始化.而那个触发点就是: ComboPooledDataSource.getConnection(); 了解上面说的"懒初始化"之后,我们来介绍C3P0中几个主要的类: ComboPooledDataSource ComboPooledDataSource: 和外界交互的类,

Snail—iOS网络学习之得到网络上的数据

在开发项目工程中,尤其是手机APP,一般都是先把界面给搭建出来,然后再从网上down数据 来填充 那么网上的数据是怎么得来的呢,网络上的数据无非就常用的两种JSON和XML 现在 大部分都是在用JSON 网络上传输数据都是以二进制形式进行传输的 ,只要我们得到网上的二进制数据 如果它是JSON的二进制形式 那么我们就可以用JSON进行解析 如果是XML,那么我们可以用XML解析 关键是怎么得到网上的二进制数据呢 设计一个常用的工具类 很简单 给我一个接口(URL),那我就可以用这个类得到二进制文

Android 中MyApplication

package liu.basedemo; import android.app.Activity; import android.app.Application; import java.lang.ref.WeakReference; import java.util.Stack; /** * MyApplication应用 基本 * Created by 刘楠 on 2016/7/28 0028.21:45 */ public class MyApplication extends Appl

Android 中BaseActivty

Base接口 IBaseActivity package liu.basedemo.base; /** * 基类接口 * Created by 刘楠 on 2016/7/28 0028.23:05 */ public interface IBaseActivity { /** * 返回视图的布局(setContentView中使用) * @return 返回视图的布局 */ int bindLayout(); /** * 初始化View(onCreate方法中调用) */ void initVi