【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

相关推荐
试行12 分钟前
Android实现自定义下拉列表绑定数据
android·java
Dingdangr5 小时前
Android中的Intent的作用
android
技术无疆5 小时前
快速开发与维护:探索 AndroidAnnotations
android·java·android studio·android-studio·androidx·代码注入
GEEKVIP5 小时前
Android 恢复挑战和解决方案:如何从 Android 设备恢复删除的文件
android·笔记·安全·macos·智能手机·电脑·笔记本电脑
Jouzzy12 小时前
【Android安全】Ubuntu 16.04安装GDB和GEF
android·ubuntu·gdb
极客先躯12 小时前
java和kotlin 可以同时运行吗
android·java·开发语言·kotlin·同时运行
Good_tea_h15 小时前
Android中的单例模式
android·单例模式
计算机源码社20 小时前
分享一个基于微信小程序的居家养老服务小程序 养老服务预约安卓app uniapp(源码、调试、LW、开题、PPT)
android·微信小程序·uni-app·毕业设计项目·毕业设计源码·计算机课程设计·计算机毕业设计开题
丶白泽20 小时前
重修设计模式-结构型-门面模式
android
晨春计1 天前
【git】
android·linux·git