【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

相关推荐
手机不死我是天子5 分钟前
《Android 核心组件深度系列 · 第 2 篇 Service》
android
前行的小黑炭20 分钟前
Compose页面切换的几种方式:Navigation、NavigationBar+HorizontalPager,会导致LaunchedEffect执行?
android·kotlin·app
前行的小黑炭1 小时前
Android :Comnpose各种副作用的使用
android·kotlin·app
BD_Marathon14 小时前
【MySQL】函数
android·数据库·mysql
西西学代码15 小时前
安卓开发---耳机的按键设置的UI实例
android·ui
maki07719 小时前
虚幻版Pico大空间VR入门教程 05 —— 原点坐标和项目优化技巧整理
android·游戏引擎·vr·虚幻·pico·htc vive·大空间
千里马学框架20 小时前
音频焦点学习之AudioFocusRequest.Builder类剖析
android·面试·智能手机·车载系统·音视频·安卓framework开发·audio
fundroid1 天前
掌握 Compose 性能优化三步法
android·android jetpack
TeleostNaCl1 天前
如何在 IDEA 中使用 Proguard 自动混淆 Gradle 编译的Java 项目
android·java·经验分享·kotlin·gradle·intellij-idea
旷野说1 天前
Android Studio Narwhal 3 特性
android·ide·android studio