Andorid N 最近任务管理器流程详解(四)
来源:互联网 发布:销售提成计算软件 编辑:程序博客网 时间:2024/06/07 00:23
4. Task的移除
本章节主要讲讲Task移除的流程
4.1 removeTask
文件:SystemServicesProxy.java
public void removeTask(final int taskId) { if (mAm == null) return; if (RecentsDebugFlags.Static.EnableMockTasks) return; // Remove the task. BackgroundThread.getHandler().post(new Runnable() { @Override public void run() { // 见4.2 mAm.removeTask(taskId); } }); }
调用AM的removeTask方法来移除Task
4.2 removeTask
文件:ActivityManagerService.java
@Override public boolean removeTask(int taskId) { // 检查是否有移除栈的权限 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()"); synchronized (this) { final long ident = Binder.clearCallingIdentity(); try { // 见4.3 return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS); } finally { Binder.restoreCallingIdentity(ident); } } }
根据任务的taskId来移除
4.3 removeTaskByIdLocked
文件:ActivityManagerService.java
private boolean removeTaskByIdLocked(int taskId, boolean killProcess, boolean removeFromRecents) { // 根据taskId找到对应的栈 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked( taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID); if (tr != null) { // 见4.3.1 调用TaskRecord的removeTaskActivitiesLocked tr.removeTaskActivitiesLocked(); // 见4.3.2 cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents); if (tr.isPersistable) { notifyTaskPersisterLocked(null, true); } return true; } Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId); return false; }
这三个参数的意思分别是:
taskId:需要被移除的task的Id
killProcess:如果可能,杀掉所有和该task相关的进程
removeFromRecents:是否将该任务从Recents中移除
这个方法调用了两个比较关键的方法,分别是removeTaskActivitiesLocked和cleanUpRemovedTaskLocked
4.3.1 removeTaskActivitiesLocked
文件:TaskRecord.java
public void removeTaskActivitiesLocked() { // 见4.3.1.1仅仅移除整个任务 performClearTaskAtIndexLocked(0); }
4.3.1.1 performClearTaskAtIndexLocked
文件:TaskRecord.java
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( // 移除该TaskRecord中的ActivityRecord对象 r, Activity.RESULT_CANCELED, null, "clear-task-index", false)) { --activityNdx; --numActivities; } } }
这个方法是真正执行移除栈,移除所有和该栈相关连的activity。参数activityNdx为0,代表要把TaskRecord内的所有Activity移除。
方法中mActivities是该TaskRecord中保存的所有的ActivityRecord对象;stack是该TaskRecord所在的ActivityStack,这里不为空(ActivityStack是一个管理者的角色,负责管理ActivityRecord和TaskRecord)
4.3.2 cleanUpRemovedTaskLocked
文件:ActivityManagerService.java
private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess, boolean removeFromRecents) { // 把该TaskRecord从mRecentTasks中移除 if (removeFromRecents) { 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; } // 如果需要,找到和这个app相关并正在运行的services,将它们停止 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent())); // 如果不需要杀进程,则返回 if (!killProcess) { return; } // Determine if the process(es) for this task should be killed. final String pkg = component.getPackageName(); ArrayList<ProcessRecord> procsToKill = new ArrayList<>(); 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 == mHomeProcess) { // Don't kill the home process along with tasks from the same package. continue; } if (!proc.pkgList.containsKey(pkg)) { // 不杀与该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) { // 如果进程中有activity属于recents中另一个不同的task,那么该进程也不杀 return; } } if (proc.foregroundServices) { // 有前台service的不杀 return; } // 添加进程到kill list // 如下情况都不杀:进程的userid和TaskRecord不同;进程是HomeProcess;和该TaskRecord无关的进程; // 进程有Activity处于其他的任务栈,并且也在recents里面的;除了上述的,其他的都加入procsToKill列表 procsToKill.add(proc); } } // 杀掉运行的进程 for (int i = 0; i < procsToKill.size(); i++) { ProcessRecord pr = procsToKill.get(i); if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND && pr.curReceiver == null) { // 立刻杀 pr.kill("remove task", true); } else { // 如果没有运行在后台,或者运行了一个receiver,就延迟杀 pr.waitingToKill = "remove task"; } } }
这个方法主要的作用就是清除进程。这里removeFromRecents为true,会先TaskRecord从mRecntTasks中移除,然后将不能杀的进程过滤掉,剩下的加入到kill list里面。最后杀进程也分为两种:
- 一种是SHED_GROUP_BACKGROUND类型并且没有正执行reciver,那就会调用kill立即去杀掉
- 另一种是简单将procsToKill中ProcessRecord的waitingToKill字段设置为remove task
- Andorid N 最近任务管理器流程详解(四)
- Andorid N 最近任务管理器流程详解(一)
- Andorid N 最近任务管理器流程详解(二)
- Andorid N 最近任务管理器流程详解(三)
- Andorid N 最近任务管理器流程详解(五)
- 转贴 详解任务管理器
- 【Windows 任务管理器进程详解】
- Windows 任务管理器进程详解
- SystemUI任务管理器缩略图获取流程
- 迭代最近点算法流程详解(ICP算法)
- 常用Windows任务管理器进程详解
- 启动Activiti流程实例以及办理任务(四)
- 任务管理器开发(一)
- 任务管理器开发(二)
- 任务管理器开发(三)
- 任务管理器
- 任务管理器
- Andorid的Activity的四种启动模式详解
- Java压缩技术(二) ZIP压缩——Java原生实现
- 决策树的python代码注解
- freescale飞思卡尔Imux6 GPIO管脚配置思路
- Hello, world !
- C#中读取和更改APP.config配置文件
- Andorid N 最近任务管理器流程详解(四)
- C#——面向对象——继承——结构和类
- AWK里面的NR、NF用法
- 算法设计与应用基础系列9
- JAVA_HOME环境变量配置
- 解决"Could not initialize class android.graphics.Typeface"
- python-memcached
- 页面之间的跳转并携带数据
- 在Linux上安装Eclipse