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

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

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

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

/**
* 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;
removeTask的更多相关文章
- Android线程管理之ThreadLocal理解及应用场景
前言: 最近在学习总结Android的动画效果,当学到Android属性动画的时候大致看了下源代码,里面的AnimationHandler存取使用了ThreadLocal,激起了我很大的好奇心以及兴趣 ...
- zone.js - 暴力之美
在ng2的开发过程中,Angular团队为我们带来了一个新的库 – zone.js.zone.js的设计灵感来源于Dart语言,它描述JavaScript执行过程的上下文,可以在异步任务之间进行持久性 ...
- C#定时任务组件之FluentScheduler
FluentScheduler是.NET开源处理定时任务组件 1.任务的创建注册 public static void TaskActionByMinutes(Action action, int c ...
- Android 中BaseActivty
Base接口 IBaseActivity package liu.basedemo.base; /** * 基类接口 * Created by 刘楠 on 2016/7/28 0028.23:05 * ...
- Android 中MyApplication
package liu.basedemo; import android.app.Activity; import android.app.Application; import java.lang. ...
- NHibernate实战详解(一)领域模型设计
关于NHibernate的资料本身就不多,中文的就更少了,好在有一些翻译文章含金量很高,另外NHibernate与Hibernate的使用方式可谓神似,所以也有不少经验可以去参考Hibernate. ...
- Android批量图片加载经典系列——采用二级缓存、异步加载网络图片
一.问题描述 Android应用中经常涉及从网络中加载大量图片,为提升加载速度和效率,减少网络流量都会采用二级缓存和异步加载机制,所谓二级缓存就是通过先从内存中获取.再从文件中获取,最后才会访问网络. ...
- android 后台附件下载
在service中通过在oncreat()中开启一个线程,轮训ArrayList<AttachmentTask> 我这个附件下载的任务list ,ArrayList<Attachme ...
- Netty源码阅读(一) ServerBootstrap启动
Netty源码阅读(一) ServerBootstrap启动 转自我的Github Netty是由JBOSS提供的一个java开源框架.Netty提供异步的.事件驱动的网络应用程序框架和工具,用以快速 ...
随机推荐
- HTML基础(2) 格式标签 文本标签
格式标签: 1.<p></p> 用来显示段落 2.<br> 控制换行 3.<nobr> </nobr> 防止浏览器将过长内容自动换行显示 ...
- MSSQL备份及数据迁移
版本:MSSQL 2008 备份情景:从A服务器的SQL 迁移到B服务器,并且数据也迁移过去. 操作环境:A服务器:WINDOWS7 B服务器:WINDOWS8.1 辅助工具:VNC 首先从A服 ...
- What's DB2 模式?
近期负责一个银行方面的项目,需要用到DB2实现多数据库版本切换.初步接触DB2,对于它的管理工具(IBM DATA STUDIO)虽然与ORACLE\MSSQL大同小异,但还是有些东西不一样的.比如什 ...
- Java随机生成定长纯数字或数字字母混合数
(转)Java随机生成定长纯数字或数字字母混合数 运行效果图: 具体实现代码
- 跨域的小小总结:js跨域及跨域的几种解决方法
一.什么是跨域?? js跨域请求就是使用js访问iframe里的不同域名下的页面内容,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同的域的iframe框架中的数据.即只要域名.协议. ...
- Quartz-2D绘图之图形上下文详解
上一篇文章大概描述了下Quartz里面大体所包含的东西,但是对具体的细节实现以及如何调用相应API却没有讲.这篇文章就先讲讲图形上下文(Graphics Context)的具体操作. 所谓Graphi ...
- Linux系统查找文件find命令使用(不断更新)
个人博客地址:http://www.cnblogs.com/wdfwolf3/. 使用格式:find [查找目录] [查找规则] [查找完后执行的操作] [查找目录] 即要查找的路径,可以使用 ...
- YII CRUD 例子
< ? php class PostTest extends CDbTestCase{ public $ fixtures = array ( 'posts' = > 'Post' , ' ...
- c语言的数组指针与指针数组
1. 数组指针:指向数组的指针是数组指针 先看下面一段代码: #include <stdio.h> int main(void) { int m[10]; printf("m = ...
- 如何在Webstorm中添加js库 (青瓷H5游戏引擎)
js等动态语言编码最大的缺点就是没有智能补全代码,webstorm做到了. qici_engine作为开发使用的库,如果能智能解析成提示再好不过了,经测试80%左右都有提示,已经很好了. 其他js库同 ...