android n task流程,Andorid N 最近任务管理器流程详解(四)

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

ArrayListprocsToKill = new ArrayList<>();

ArrayMap> pmap = mProcessNames.getMap();

for (int i = 0; i < pmap.size(); i++) {

SparseArrayuids = 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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值