b站免费视频教程讲解:
https://www.bilibili.com/video/BV1wj411o7A9/
TaskView的创建调用栈:
实际上这里创建的调用栈是,但是这里明显使用的ViewPool这种方式,主要是为了减少频繁创建的,所以就干脆缓存到ViewPool中,需要用时候再拿出来
什么时候到ViewPool中获取呢?具体获取调用链如下:
07-29 17:50:08.170 1065 1065 I lsm444 : java.lang.Exception
07-29 17:50:08.170 1065 1065 I lsm444 : at com.android.quickstep.views.RecentsView.getTaskViewFromPool(RecentsView.java:2085)
07-29 17:50:08.170 1065 1065 I lsm444 : at com.android.quickstep.views.RecentsView.applyLoadPlan(RecentsView.java:1443)
07-29 17:50:08.170 1065 1065 I lsm444 : at com.android.quickstep.views.RecentsView$$ExternalSyntheticLambda19.accept(Unknown Source:4)
07-29 17:50:08.170 1065 1065 I lsm444 : at com.android.quickstep.RecentTasksList.lambda$getTasks$3$com-android-quickstep-RecentTasksList(RecentTasksList.java:132)
07-29 17:50:08.170 1065 1065 I lsm444 : at com.android.quickstep.RecentTasksList$$ExternalSyntheticLambda4.run(Unknown Source:6)
07-29 17:50:08.170 1065 1065 I lsm444 : at android.os.Handler.handleCallback(Handler.java:942)
07-29 17:50:08.170 1065 1065 I lsm444 : at android.os.Handler.dispatchMessage(Handler.java:99)
07-29 17:50:08.170 1065 1065 I lsm444 : at android.os.Looper.loopOnce(Looper.java:201)
07-29 17:50:08.170 1065 1065 I lsm444 : at android.os.Looper.loop(Looper.java:288)
07-29 17:50:08.170 1065 1065 I lsm444 : at android.app.ActivityThread.main(ActivityThread.java:7898)
07-29 17:50:08.170 1065 1065 I lsm444 : at java.lang.reflect.Method.invoke(Native Method)
07-29 17:50:08.170 1065 1065 I lsm444 : at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
07-29 17:50:08.170 1065 1065 I lsm444 : at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
上面可以看出主要是通过RecentsView.applyLoadPlan方法,这个其实是从getTasks这个方法里面进行调用的
public synchronized int getTasks(boolean loadKeysOnly,
Consumer<ArrayList<GroupTask>> callback) {
//省略
UI_HELPER_EXECUTOR.execute(() -> {
if (!mResultsBg.isValidForRequest(requestLoadId, loadKeysOnly)) {
mResultsBg = loadTasksInBackground(Integer.MAX_VALUE, requestLoadId, loadKeysOnly);
}
TaskLoadResult loadResult = mResultsBg;
mMainThreadExecutor.execute(() -> {
if (callback != null) {
ArrayList<GroupTask> result = copyOf(mResultsUi);
callback.accept(result);//这里进行的调用applyLoadPlan
}
});
});
return requestLoadId;
}
那么又是哪里调用到的getTasks这个方法呢?
getTask的调用链如下:
07-29 17:50:08.161 1065 1065 I lsm444 : getTasks
07-29 17:50:08.161 1065 1065 I lsm444 : java.lang.Exception
07-29 17:50:08.161 1065 1065 I lsm444 : at com.android.quickstep.RecentTasksList.getTasks(RecentTasksList.java:119)
07-29 17:50:08.161 1065 1065 I lsm444 : at com.android.quickstep.RecentsModel.getTasks(RecentsModel.java:102)
07-29 17:50:08.161 1065 1065 I lsm444 : at com.android.quickstep.views.RecentsView.reloadIfNeeded(RecentsView.java:2103)
07-29 17:50:08.161 1065 1065 I lsm444 : at com.android.quickstep.views.RecentsView.updateTaskStackListenerState(RecentsView.java:1634)
07-29 17:50:08.161 1065 1065 I lsm444 : at com.android.quickstep.views.RecentsView.setOverviewStateEnabled(RecentsView.java:1178)
07-29 17:50:08.161 1065 1065 I lsm444 : at com.android.quickstep.views.LauncherRecentsView.setOverviewStateEnabled(LauncherRecentsView.java:133)
07-29 17:50:08.161 1065 1065 I lsm444 : at com.android.quickstep.views.LauncherRecentsView.onStateTransitionStart(LauncherRecentsView.java:100)
07-29 17:50:08.161 1065 1065 I lsm444 : at com.android.quickstep.views.LauncherRecentsView.onStateTransitionStart(LauncherRecentsView.java:49)
07-29 17:50:08.161 1065 1065 I lsm444 : at com.android.launcher3.statemanager.StateManager.onStateTransitionStart(StateManager.java:353)
07-29 17:50:08.161 1065 1065 I lsm444 : at com.android.launcher3.statemanager.StateManager.-$$Nest$monStateTransitionStart(Unknown Source:0)
07-29 17:50:08.161 1065 1065 I lsm444 : at com.android.launcher3.statemanager.StateManager$1.onAnimationStart(StateManager.java:338)
07-29 17:50:08.161 1065 1065 I lsm444 : at android.animation.Animator$AnimatorListener.onAnimationStart(Animator.java:584)
07-29 17:50:08.161 1065 1065 I lsm444 : at android.animation.AnimatorSet.start(AnimatorSet.java:737)
07-29 17:50:08.161 1065 1065 I lsm444 : at android.animation.AnimatorSet.start(AnimatorSet.java:684)
07-29 17:50:08.161 1065 1065 I lsm444 : at com.android.launcher3.statemanager.StateManager$StartAnimRunnable.run(StateManager.java:503)
07-29 17:50:08.161 1065 1065 I lsm444 : at android.os.Handler.handleCallback(Handler.java:942)
07-29 17:50:08.161 1065 1065 I lsm444 : at android.os.Handler.dispatchMessage(Handler.java:99)
07-29 17:50:08.161 1065 1065 I lsm444 : at android.os.Looper.loopOnce(Looper.java:201)
07-29 17:50:08.161 1065 1065 I lsm444 : at android.os.Looper.loop(Looper.java:288)
07-29 17:50:08.161 1065 1065 I lsm444 : at android.app.ActivityThread.main(ActivityThread.java:7898)
07-29 17:50:08.161 1065 1065 I lsm444 : at java.lang.reflect.Method.invoke(Native Method)
07-29 17:50:08.161 1065 1065 I lsm444 : at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
07-29 17:50:08.161 1065 1065 I lsm444 : at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
TaskInfo相关的数据加载:
/**
* Loads and creates a list of all the recent tasks.
*/
@VisibleForTesting
TaskLoadResult loadTasksInBackground(int numTasks, int requestId, boolean loadKeysOnly) {
int currentUserId = Process.myUserHandle().getIdentifier();
//调用到sysui端的getRecentTasks
ArrayList<GroupedRecentTaskInfo> rawTasks =
mSysUiProxy.getRecentTasks(numTasks, currentUserId);
//省略
return allTasks;
}
这里其实会调用的sysui的getRecentTasks进行查询
这里其实是一个跨进程通信:
frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
private static class IRecentTasksImpl extends IRecentTasks.Stub {
//省略
@Override
public GroupedRecentTaskInfo[] getRecentTasks(int maxNum, int flags, int userId)
//省略
这里核心又调用到了controller的getRecentTasks
executeRemoteCallWithTaskPermission(mController, "getRecentTasks",
(controller) -> out[0] = controller.getRecentTasks(maxNum, flags, userId)
.toArray(new GroupedRecentTaskInfo[0]),
true /* blocking */);
return out[0];
}
}
@VisibleForTesting
ArrayList<GroupedRecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
// Note: the returned task list is from the most-recent to least-recent order
//调用到了getRawRecentTasks方法
final List<ActivityManager.RecentTaskInfo> rawList = getRawRecentTasks(maxNum, flags,
userId);
//以下操作主要是为了分屏相关的task可以作为一个整体返回,一般把它们搞成一个gouped,有task1和task2
// Pull out the pairs as we iterate back in the list
ArrayList<GroupedRecentTaskInfo> recentTasks = new ArrayList<>();
for (int i = 0; i < rawList.size(); i++) {
final ActivityManager.RecentTaskInfo taskInfo = rawList.get(i);
if (!rawMapping.contains(taskInfo.taskId)) {
// If it's not in the mapping, then it was already paired with another task
continue;
}
final int pairedTaskId = mSplitTasks.get(taskInfo.taskId);
if (pairedTaskId != INVALID_TASK_ID && rawMapping.contains(pairedTaskId)) {
final ActivityManager.RecentTaskInfo pairedTaskInfo = rawMapping.get(pairedTaskId);
rawMapping.remove(pairedTaskId);
recentTasks.add(new GroupedRecentTaskInfo(taskInfo, pairedTaskInfo,
mTaskSplitBoundsMap.get(pairedTaskId)));
} else {
recentTasks.add(new GroupedRecentTaskInfo(taskInfo));
}
}
return recentTasks;
}
@VisibleForTesting
List<ActivityManager.RecentTaskInfo> getRawRecentTasks(int maxNum, int flags, int userId) {
//本质就是调用到了atms的getRecentTasks方法
return ActivityTaskManager.getInstance().getRecentTasks(maxNum, flags, userId);
}
上面获取RecentTask的信息就已经完成,总结一下:
1、桌面调用到sysui获取Task信息,因为sysui中其实有分屏相关的TecentTask信息
2、sysui也是调用到atms进行RecentTask的信息获取
07-30 00:56:38.758 1059 1059 I lsm444 : setThumbnail task = [id=16 windowingMode=0 user=0 lastActiveTime=18031] null thumbnailData = com.android.systemui.shared.recents.model.ThumbnailData@57b6fdb
07-30 00:56:38.758 1059 1059 I lsm444 : java.lang.Exception
07-30 00:56:38.758 1059 1059 I lsm444 : at com.android.quickstep.views.TaskThumbnailView.setThumbnail(TaskThumbnailView.java:150)
07-30 00:56:38.758 1059 1059 I lsm444 : at com.android.quickstep.views.TaskThumbnailView.setThumbnail(TaskThumbnailView.java:162)
07-30 00:56:38.758 1059 1059 I lsm444 : at com.android.quickstep.views.TaskView.lambda$onTaskListVisibilityChanged$5$com-android-quickstep-views-TaskView(TaskView.java:819)
07-30 00:56:38.758 1059 1059 I lsm444 : at com.android.quickstep.views.TaskView$$ExternalSyntheticLambda3.accept(Unknown Source:4)
07-30 00:56:38.758 1059 1059 I lsm444 : at com.android.quickstep.TaskThumbnailCache.lambda$updateThumbnailInBackground$1(TaskThumbnailCache.java:147)
07-30 00:56:38.758 1059 1059 I lsm444 : at com.android.quickstep.TaskThumbnailCache$$ExternalSyntheticLambda0.accept(Unknown Source:6)
07-30 00:56:38.758 1059 1059 I lsm444 : at com.android.quickstep.TaskThumbnailCache$1.handleResult(TaskThumbnailCache.java:173)
07-30 00:56:38.758 1059 1059 I lsm444 : at com.android.quickstep.TaskThumbnailCache$1.handleResult(TaskThumbnailCache.java:163)
07-30 00:56:38.758 1059 1059 I lsm444 : at com.android.quickstep.util.CancellableTask.lambda$run$0$com-android-quickstep-util-CancellableTask(CancellableTask.java:43)
07-30 00:56:38.758 1059 1059 I lsm444 : at com.android.quickstep.util.CancellableTask$$ExternalSyntheticLambda0.run(Unknown Source:4)
07-30 00:56:38.758 1059 1059 I lsm444 : at android.os.Handler.handleCallback(Handler.java:942)
07-30 00:56:38.758 1059 1059 I lsm444 : at android.os.Handler.dispatchMessage(Handler.java:99)
07-30 00:56:38.758 1059 1059 I lsm444 : at android.os.Looper.loopOnce(Looper.java:201)
07-30 00:56:38.758 1059 1059 I lsm444 : at android.os.Looper.loop(Looper.java:288)
07-30 00:56:38.758 1059 1059 I lsm444 : at android.app.ActivityThread.main(ActivityThread.java:7898)
07-30 00:56:38.758 1059 1059 I lsm444 : at java.lang.reflect.Method.invoke(Native Method)
07-30 00:56:38.758 1059 1059 I lsm444 : at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
07-30 00:56:38.758 1059 1059 I lsm444 : at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
设置相关的缩略图由以下代码触发:
public void onTaskListVisibilityChanged(boolean visible, @TaskDataChanges int changes) {
if (visible) {
// These calls are no-ops if the data is already loaded, try and load the high
// resolution thumbnail if the state permits
RecentsModel model = RecentsModel.INSTANCE.get(getContext());
TaskThumbnailCache thumbnailCache = model.getThumbnailCache();
TaskIconCache iconCache = model.getIconCache();
if (needsUpdate(changes, FLAG_UPDATE_THUMBNAIL)) {
//这里进行相关加载缩略图加载
mThumbnailLoadRequest = thumbnailCache.updateThumbnailInBackground(
mTask, thumbnail -> {
//加载完成后进行回调
mSnapshotView.setThumbnail(mTask, thumbnail);
});
}
//省略
}
接下来看updateThumbnailInBackground方法:
public CancellableTask updateThumbnailInBackground(
Task task, Consumer<ThumbnailData> callback) {
Preconditions.assertUIThread();
//省略
return updateThumbnailInBackground(task.key, !mHighResLoadingState.isEnabled(), t -> {
//加在完成后的回调有
task.thumbnail = t;
callback.accept(t);
});
}
再来看看updateThumbnailInBackground方法实现:
private CancellableTask updateThumbnailInBackground(TaskKey key, boolean lowResolution,
Consumer<ThumbnailData> callback) {
Preconditions.assertUIThread();
ThumbnailData cachedThumbnail = mCache.getAndInvalidateIfModified(key);
if (cachedThumbnail != null && cachedThumbnail.thumbnail != null
&& (!cachedThumbnail.reducedResolution || lowResolution)) {
// Already cached, lets use that thumbnail
callback.accept(cachedThumbnail);
return null;
}
CancellableTask<ThumbnailData> request = new CancellableTask<ThumbnailData>() {
@Override
public ThumbnailData getResultOnBg() {
//最终其实是通过传递taskId到ams中获取对应的缩略图
return ActivityManagerWrapper.getInstance().getTaskThumbnail(
key.id, lowResolution);
}
@Override
public void handleResult(ThumbnailData result) {
mCache.put(key, result);
callback.accept(result);
}
};
mBgExecutor.execute(request);
return request;
}