【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

相关推荐
人生游戏牛马NPC1号5 分钟前
学习 Android (十七) 学习 OpenCV (二)
android·opencv·学习
恋猫de小郭39 分钟前
谷歌开启 Android 开发者身份验证,明年可能开始禁止“未经验证”应用的侧载,要求所有开发者向谷歌表明身份
android·前端·flutter
用户091 小时前
Gradle声明式构建总结
android
用户091 小时前
Gradle插件开发实践总结
android
Digitally12 小时前
如何将视频从安卓设备传输到Mac?
android·macos
alexhilton13 小时前
Compose Unstyled:Compose UI中失传的设计系统层
android·kotlin·android jetpack
刘龙超15 小时前
如何应对 Android 面试官 -> 玩转 RxJava (基础使用)
android·rxjava
柿蒂16 小时前
从动态缩放自定义View,聊聊为什么不要把问题复杂化
android·ai编程·android jetpack
kerli16 小时前
kotlin协程系列:callbackFlow
android·kotlin
没有了遇见18 小时前
Android 原生定位实现(替代融合定位收费,获取经纬度方案)
android·kotlin