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提供异步的.事件驱动的网络应用程序框架和工具,用以快速 ...
随机推荐
- oracle 消除块竞争(hot blocks)
上篇日志提到了,那么高的负载,是存在数据块读竞争,下面介绍几个方法来消除块竟争 查找块竟争 SELECT p1 "file#", p2 "block#", p3 ...
- Ubuntu1404+Django1.9+Apache2.4部署配置2配置文件设置
转载注明出处,个人博客:http://www.cnblogs.com/wdfwolf3/ Django首要的部署平台是WSGI,它是Python Web服务器和应用的标准.使用Apache和mod_w ...
- 设计模式之 Singleton 单例模式
先上两段代码,区别仅在于是否涉及线程安全. 首先是不涉及多线程的单例: public class Singleton { private final static Singleton INSTANCE ...
- html引入外部的jswenjian
首先看一下引入的方式是否正确 <script type='text/javascript' src='xx.js'></script> 其次看引入的路径是否正确 如果引入了第三 ...
- JavaScript学习总结【3】、JS对象
在 JS 中一切皆对象,并提供了多个内置对象,比如:String.Array.Date 等,此外还支持自定义对象.对象只是一种特殊类型的数据,并拥有属性和方法,属性是与对象相关的值,方法是能够在对象上 ...
- php Imagick库readImage()报Postscript delegate failed 解决方法(失效)
需要安装 ghostscript http://www.ghostscript.com/download/gsdnld.html
- python中的字典应用实例
字典中的键使用时必须满足一下两个条件: 1.每个键只能对应一个项,也就是说,一键对应多个值时不允许的(列表.元组和其他字典的容器对象除外).当有键发生冲突时(即字典键重复赋值),取最后的赋值. > ...
- css:中文词不断开,整体换行
一.问题 关于文字的换行与不换行的问题有些特殊情况,是使用css的word-break等属性实现不了的,下面的情况就证明了: 我们想要的效果是,一个词整体换行或不换行,“兼职测试”可以都换至第二行 ...
- mvc Model元数据【学习笔记】
页面中Html.Editorfor(model=>model.fieldname)这些方法,都是通过Model的元数据来生成html的,我们如果想控制最终生成的html,可以通过修改元数据来实现 ...
- 关于android app两次点击返回键退出的处理
现在的android app在开发时,引入了两次点击返回键退出app的设计 为了避免用户误触,这个设计很人性化 中文网上社区有些同学贴了一些实现的例子,我觉得不是很好 代码如下 public bool ...