【Android 13】WMS/AMS 常见方法调用提取

整理分析 WMS/AMS 流程中经常出现的公用代码逻辑。

1. forAllLeafTasks

以Activity启动流程 TaskDisplayArea::pauseBackTasks 调用为例。 forAllLeafTasks方法定义在WindowContainer类中,TaskDisplayArea是容器,自然也是其子类

scss 复制代码
# WindowContainer

    // traverseTopToBottom表示从上到下还是从下到上
    // 当前案例传递的是true
    void forAllLeafTasks(Consumer<Task> callback, boolean traverseTopToBottom) {
        final int count = mChildren.size();
        if (traverseTopToBottom) {
            for (int i = count - 1; i >= 0; --i) {
                // 遍历调用每个孩子的forAllLeafTasks
                mChildren.get(i).forAllLeafTasks(callback, traverseTopToBottom);
            }
        } else {
            for (int i = 0; i < count; i++) {
                mChildren.get(i).forAllLeafTasks(callback, traverseTopToBottom);
            }
        }
    }

TaskDisplayArea的孩子是 Task,从堆栈信息也知道会调用到 Task::forAllLeafTasks

ini 复制代码
# Task
   @Override
    void forAllLeafTasks(Consumer<Task> callback, boolean traverseTopToBottom) {
        final int count = mChildren.size();
        // 定义变量是否为 LeafTask
        boolean isLeafTask = true;
        if (traverseTopToBottom) {
            for (int i = count - 1; i >= 0; --i) {
                // 遍历所有子容器,如果下面还有Task,则isLeafTask = false,表示不是LeafTask然后继续递归调用
                final Task child = mChildren.get(i).asTask();
                if (child != null) {
                    isLeafTask = false;
                    child.forAllLeafTasks(callback, traverseTopToBottom);
                }
            }
        } else {
            for (int i = 0; i < count; i++) {
                final Task child = mChildren.get(i).asTask();
                if (child != null) {
                    isLeafTask = false;
                    child.forAllLeafTasks(callback, traverseTopToBottom);
                }
            }
        }
        // 如果当前是LeafTask,则执行回调
        if (isLeafTask) callback.accept(this);
    }

LeafTask表示是否为叶子Task,根据代码也知道就是下面没有Task了。

小结

综上forAllLeafTasks其实就是执行对当前容器下每个叶子Task执行参数的回调,那如果有多个叶子Task必然是执行多次。

2. forAllLeafTaskFragments

以Activity启动流程 TaskDisplayArea::pauseBackTasks,参考forAllLeafTasks的调用。

ini 复制代码
# WindowContainer
    void forAllLeafTaskFragments(Consumer<TaskFragment> callback, boolean traverseTopToBottom) {
        final int count = mChildren.size();
        if (traverseTopToBottom) {
            for (int i = count - 1; i >= 0; --i) {
                mChildren.get(i).forAllLeafTaskFragments(callback, traverseTopToBottom);
            }
        } else {
            for (int i = 0; i < count; i++) {
                mChildren.get(i).forAllLeafTaskFragments(callback, traverseTopToBottom);
            }
        }
    }

与forAllLeafTasks一样,也是调用每个子容器的forAllLeafTaskFragments,具体调用到TaskFragment

ini 复制代码
# TaskFragment
    @Override
    void forAllLeafTaskFragments(Consumer<TaskFragment> callback, boolean traverseTopToBottom) {
        final int count = mChildren.size();
        // 标记是否为LeafTaskFrag
        boolean isLeafTaskFrag = true;
        if (traverseTopToBottom) {
            for (int i = count - 1; i >= 0; --i) {
                // 如果下面没有TaskFragment,那么当前就是 叶子TaskFragment
                final TaskFragment child = mChildren.get(i).asTaskFragment();
                if (child != null) {
                    isLeafTaskFrag = false;
                    child.forAllLeafTaskFragments(callback, traverseTopToBottom);
                }
            }
        } else {
            for (int i = 0; i < count; i++) {
                final TaskFragment child = mChildren.get(i).asTaskFragment();
                if (child != null) {
                    isLeafTaskFrag = false;
                    child.forAllLeafTaskFragments(callback, traverseTopToBottom);
                }
            }
        }
        if (isLeafTaskFrag) callback.accept(this);
    }

小结

综上其实就是执行对当前容器下每个叶子TaskFragment执行参数的回调,那如果有多个叶子TaskFragment必然是执行多次。

3. Activity生命周期事务

以Activity启动流程为例

ClientTransaction 通用逻辑

ActivityTaskSupervisor::realStartActivityLocked 构建 LaunchActivityItem

ClientLifecycleManager::scheduleTransaction ClientTransaction::schedule ActivityThread::scheduleTransaction ClientTransactionHandler::scheduleTransaction ---ActivityThread的父类,发送消息EXECUTE_TRANSACTION ActivityThread::handleMessage ---处理消息EXECUTE_TRANSACTION TransactionExecutor::execute TransactionExecutor::executeCallbacks ---处理 Callbacks ,比如LaunchActivityItem ClientTransactionItem::execute -- ClientTransactionItem 只是父类,具体看具体传递的对象 ClientTransactionItem::postExecute TransactionExecutor::executeLifecycleState ---处理生命周期状态相关,也就是 ResumeActivityItem 这些

以 Activity启动的调用 ActivityTaskSupervisor::realStartActivityLocked为例

4. 容器通用逻辑提取

4.1 容器的 forAllRootTasks 流程

起点为WindowContainer.forAllRootTasks

arduino 复制代码
# WindowContainer
        // Consumer 接口
        void forAllRootTasks(Consumer<Task> callback) {
            // 调用重载,第二个参数为true
            forAllRootTasks(callback, true /* traverseTopToBottom */);
        }
        void forAllRootTasks(Consumer<Task> callback, boolean traverseTopToBottom) {
            int count = mChildren.size();
            if (traverseTopToBottom) {
                for (int i = count - 1; i >= 0; --i) {
                    //  只有Task 重新了该方法
                    mChildren.get(i).forAllRootTasks(callback, traverseTopToBottom);
                }
            } else {
                ......忽略
            }
         }
         
        // Predicate 接口
        boolean forAllRootTasks(Predicate<Task> callback) {
            return forAllRootTasks(callback, true /* traverseTopToBottom */);
        }

        boolean forAllRootTasks(Predicate<Task> callback, boolean traverseTopToBottom) {
            int count = mChildren.size();
            if (traverseTopToBottom) {
                for (int i = count - 1; i >= 0; --i) {
                    if (mChildren.get(i).forAllRootTasks(callback, traverseTopToBottom)) {
                        return true;
                    }
                }
            } else {
                ......忽略
            }
            return false;
        }
// 如果是用AS ,或者在源码上搜索,可知只有 Task 重写了forAllRootTasks函数。 
// 所以调用子容器的forAllRootTasks ,最后只会调用到Task 类中。 根据打印的堆栈信息也确实如此。
# Task 
    @Override
    void forAllRootTasks(Consumer<Task> callback, boolean traverseTopToBottom) {
        if (isRootTask()) {
            // 如果当前是 rooTask 则直接执行回调
            //  对于Task,第二个参数没有使用,将自己传递给了接口函数
            callback.accept(this);
        }
    }
    @Override
    boolean forAllRootTasks(Predicate<Task> callback, boolean traverseTopToBottom) {
        return isRootTask() ? callback.test(this) : false;
    }

其实就是相当于在 Task 这个容器里, 去调用传进来的接口回调。这个接口定义如下

csharp 复制代码
# Consumer
public interface Consumer<T> {
    // 其实就是调用 这个了
    void accept(T var1);

    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (t) -> {
            this.accept(t);
            after.accept(t);
        };
    }
}
# Predicate 
public interface Predicate<T> {
    boolean test(T var1);
    // 忽略其他方法
}

所以这部分的逻辑只需要看调用 forAllRootTasks 时 看传递进来的接口实现类是哪一个,找打对应的的 accept 或者 test函数即可,另外注意的是泛型参数都是 Task

4.2容器的 forAllActivities 流程

这个是处理 Activity 的, 而 Activity 对于的容器 一般就是 ActivityRecord

typescript 复制代码
# WindowContainer
    // Consumer 类型
    void forAllActivities(Consumer<ActivityRecord> callback) {
        // 泛型要求为 ActivityRecord,第二个参数为true
        forAllActivities(callback, true /*traverseTopToBottom*/);
    }
    void forAllActivities(Consumer<ActivityRecord> callback, boolean traverseTopToBottom) {
        if (traverseTopToBottom) {
            for (int i = mChildren.size() - 1; i >= 0; --i) {
                mChildren.get(i).forAllActivities(callback, traverseTopToBottom);
            }
        } else {
            ......忽略逻辑
        }
    }
    // Predicate 类型
    boolean forAllActivities(Predicate<ActivityRecord> callback) {
        // 泛型要求为 ActivityRecord,第二个参数为true
        return forAllActivities(callback, true /*traverseTopToBottom*/);
    }

    boolean forAllActivities(Predicate<ActivityRecord> callback, boolean traverseTopToBottom) {
        if (traverseTopToBottom) {
            for (int i = mChildren.size() - 1; i >= 0; --i) {
                if (mChildren.get(i).forAllActivities(callback, traverseTopToBottom)) return true;
            }
        } else {
            ......忽略逻辑
        }
        return false;
    }

目前也只有 ActivityRecord 重写了 forAllActivities

typescript 复制代码
# ActivityRecord
    @Override
    void forAllActivities(Consumer<ActivityRecord> callback, boolean traverseTopToBottom) {
        callback.accept(this);
    }
    @Override
    boolean forAllActivities(Predicate<ActivityRecord> callback, boolean traverseTopToBottom) {
        return callback.test(this);
    }

可以看到逻辑与forAllRootTasks类似, 找到对应类型的接口看 对应的 accept或者test方法实现即可,泛型参数都是 ActivityRecord

相关推荐
雨白1 小时前
Jetpack系列(二):Lifecycle与LiveData结合,打造响应式UI
android·android jetpack
kk爱闹3 小时前
【挑战14天学完python和pytorch】- day01
android·pytorch·python
每次的天空5 小时前
Android-自定义View的实战学习总结
android·学习·kotlin·音视频
恋猫de小郭5 小时前
Flutter Widget Preview 功能已合并到 master,提前在体验毛坯的预览支持
android·flutter·ios
断剑重铸之日6 小时前
Android自定义相机开发(类似OCR扫描相机)
android
随心最为安6 小时前
Android Library Maven 发布完整流程指南
android
岁月玲珑6 小时前
【使用Android Studio调试手机app时候手机老掉线问题】
android·ide·android studio
还鮟10 小时前
CTF Web的数组巧用
android
小蜜蜂嗡嗡12 小时前
Android Studio flutter项目运行、打包时间太长
android·flutter·android studio
aqi0012 小时前
FFmpeg开发笔记(七十一)使用国产的QPlayer2实现双播放器观看视频
android·ffmpeg·音视频·流媒体