Android11 以Window的视角来看FallbackHome的启动

在WMS中,使用WindowState代表着一个Window并维护着一个Window的"层级树",每个Window需要按照"层级"的规则进行排列。对于FallbackHome,其Window是挂载在home task上,而home task挂载在DefaultTaskDisplayArea这个叶子节点下,其父子关系如下:
在这里插入图片描述
1,home Task
home Task 在 SystemServer启动的时候,就会创建

//frameworks/base/services/java/com/android/server/SystemServer.java
private void startOtherServices(@NonNull TimingsTraceAndSlog t) {//省略t.traceBegin("SetWindowManagerService");mActivityManagerService.setWindowManager(wm);t.traceEnd();//省略
}

AMS.setWindowManager

//frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public void setWindowManager(WindowManagerService wm) {synchronized (this) {mWindowManager = wm;mWmInternal = LocalServices.getService(WindowManagerInternal.class);mActivityTaskManager.setWindowManager(wm);}
}

ATMS.setWindowManager

public void setWindowManager(WindowManagerService wm) {synchronized (mGlobalLock) {//省略mRootWindowContainer.setWindowManager(wm);}}

RootWindowContainer.setWindowManager

//frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
void setWindowManager(WindowManagerService wm) {//省略final TaskDisplayArea defaultTaskDisplayArea = getDefaultTaskDisplayArea();defaultTaskDisplayArea.getOrCreateRootHomeTask(ON_TOP);//省略}

先获取defaultTaskDisplayArea ,然后调用其getOrCreateRootHomeTask去创建home Task

//frameworks/base/services/core/java/com/android/server/wm/TaskDisplayArea.java
ActivityStack getOrCreateRootHomeTask(boolean onTop) {ActivityStack homeTask = getRootHomeTask();if (homeTask == null && mDisplayContent.supportsSystemDecorations()) {homeTask = createStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME, onTop);}return homeTask;}

如果home Task没有创建过的话,就调用createStack去创建,传入的参数中,type为ACTIVITY_TYPE_HOME。在createStack方法中,继续调用createStackUnchecked

//frameworks/base/services/core/java/com/android/server/wm/TaskDisplayArea.java
ActivityStack createStackUnchecked(int windowingMode, int activityType, int stackId,boolean onTop, ActivityInfo info, Intent intent, boolean createdByOrganizer) {final ActivityStack stack = new ActivityStack(mAtmService, stackId, activityType,info, intent, createdByOrganizer);//1if (launchRootTask != null) {//省略} else {addChild(stack, onTop ? POSITION_TOP : POSITION_BOTTOM);//2stack.setWindowingMode(windowingMode, true /* creating */);}return stack;}

注释1处,创建ActivityStack 对象,ActivityStack 继承自Task,注释2处将该ActivityStack设置为当前对象即defaultTaskDisplayArea的孩子。所以经过以上的调用流程,创建了一个home Task,其实home Task就是ActivityStack对象,然后挂载到DefaultTaskDisplayArea下。

2,FallbackHome Task

FallbackHome 是在 ActivityManagerService的 systemReady 中,调用startHomeOnAllDisplays 启动的,startHomeOnAllDisplays 会调用的ActivityStarter的executeRequest方法,从这个方法开始分析

//frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
private int executeRequest(Request request) {//省略final ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,callingPackage, callingFeatureId, intent, resolvedType, aInfo,mService.getGlobalConfiguration(), resultRecord, resultWho, requestCode,request.componentSpecified, voiceSession != null, mSupervisor, checkedOptions,sourceRecord);//创建 ActivityRecord ,继承WindowToken//省略mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,restrictedBgActivity, intentGrants);
}

先创建一个ActivityRecord 对象,然后调用startActivityUnchecked继续处理。该方法最后调用setNewTask来创建Task

//frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
private void setNewTask(Task taskToAffiliate) {final boolean toTop = !mLaunchTaskBehind && !mAvoidMoveToFront;final Task task = mTargetStack.reuseOrCreateTask(mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,mVoiceInteractor, toTop, mStartActivity, mSourceRecord, mOptions);//1addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask");//2//省略}

注释1处创建FallbackHome Task,mTargetStack为前面创建的home Task。注释2处,将前面创建的ActivityRecord设置为FallbackHome Task的孩子。

//frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
Task reuseOrCreateTask(ActivityInfo info, Intent intent, IVoiceInteractionSession voiceSession,IVoiceInteractor voiceInteractor, boolean toTop, ActivityRecord activity,ActivityRecord source, ActivityOptions options) {Task task;if (DisplayContent.alwaysCreateStack(getWindowingMode(), getActivityType())) {//省略} else {//省略task = new ActivityStack(mAtmService, taskId, info, intent, voiceSession,voiceInteractor, null /* taskDescription */, this);//新建task // add the task to stack first, mTaskPositioner might need the stack associationaddChild(task, toTop, (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0);//添加为home Task的孩子}//省略return task;}

可以看出,FallbackHome Task也是一个ActivityStack对象,FallbackHome Task的父亲为home Task

3,ActivityRecord

前面提到过,在executeRequest方法中创建ActivityRecord,最后调用到addOrReparentStartingActivity方法

//frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.javaprivate void addOrReparentStartingActivity(Task parent, String reason) {if (mStartActivity.getTask() == null || mStartActivity.getTask() == parent) {parent.addChild(mStartActivity);//1} else {mStartActivity.reparent(parent, parent.getChildCount() /* top */, reason);}}

注释1处,parent为前面创建的FallbackHome Task,mStartActivity为前面创建的ActivityRecord,将ActivityRecord设置为FallbackHome Task的孩子

4,WindowState
在FallbackHome 的resume流程中,会调用ViewRootImpl的setView方法,最终调用到WMS的addWindow

//frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
public int addWindow(/*省略*/) {//省略final WindowState win = new WindowState(this, session, client, token, parentWindow,appOp[0], seq, attrs, viewVisibility, session.mUid, userId,session.mCanAddInternalSystemWindow);//创建WindowState//省略win.mToken.addWindow(win);//省略
}

这里的win.mToken就是前面创建的ActivityRecord对象

//frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java
@Overridevoid addWindow(WindowState w) {super.addWindow(w);//删除}

调用其父类也就是WindowToken的addWindow方法

void addWindow(final WindowState win) {//省略if (!mChildren.contains(win)) {addChild(win, mWindowComparator);mWmService.mWindowsChanged = true;}}

也是通过addChild将该WindowState设置为ActivityRecord的孩子

总结

本文以Window的视角来分析了一下FallbackHome的显示流程。我们知道了在WMS中,使用WindowState来代表一个窗口。WindowState的父亲是ActivityRecord,也就是说在WMS的层级树中,FallbackHome对应的WindowState挂载在ActivityRecord下。ActivityRecord挂载在FallbackHome Task(ActivityStack)下,FallbackHome Task又挂载在home Task(ActivityStack)下。而home Task的父亲是DefaultTaskDisplayArea

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/29151.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python之日志(三)--将捕获的异常写入日志中

1.日志级别 import logging #日志模块 #默认下只会从第3级开始打印 logging.debug(DEBUG级别) #1级 logging.info(INFO级别) #2级 logging.warning(WARNING级别) #3级 logging.error(ERROR级别) #4级 logging.critical(CRITICAL级别) #5级 默认第1和第2级的日志不会打印 …

解决 uniapp h5 页面在私有企微iOS平台 间歇性调用uni api不成功问题(uni.previewImage为例)。

demo <template><view class"content"><image class"logo" src"/static/logo.png"></image><button click"previewImage">预览图片</button></view> </template><script> //打…

React@16.x(32)useDebugValue

目录 1&#xff0c;介绍2&#xff0c;作用 1&#xff0c;介绍 从一个例子开始&#xff1a; export default function App() {const [n, setN] useState(0);const refH1 useRef();useEffect(() > {console.log("父组件");});return <h1 ref{refH1}>{n}&l…

使用 imu_utils 、Kalibr 工具进行IMU和相机内外参外参标定

文章目录 一、问题描述二、imu_utils 工具的使用1. 安装1.1 下载与编译1.2 编译bug解决 2. 标定 IMU2.1 imu bag包录制2.1.1 imu 数据格式2.1.2 imu 数据录制 2.2 imu 标定 三、Kalibr 工具的使用1. 安装1.1 下载与编译1.2 问题解决 一、问题描述 vins系列安装完成后&#xff…

EasyRecovery电脑数据恢复软件2024数据守护神#误删文件神器#硬盘恢复利器#数据丢失救星

&#x1f310; 你是否曾经因为误删文件、硬盘损坏等原因&#xff0c;失去了重要的数据&#xff1f;别担心&#xff0c;EasyRecovery电脑数据恢复软件是你的救星&#xff01;它能够帮你找回丢失的文件&#xff0c;让你的数据重新焕发生机。 &#x1f50d; EasyRecovery软件的核…

有关健身的俄语表达,柯桥零基础俄语培训

фитнес 健身 тренер 教练 абонемент 会员卡 аэробика 有氧运动 анаэробика 无氧运动 плавание 游泳 пробежка / бег трусцой 慢跑 беговая дорожка 跑步机 йога 瑜伽 коври…

持续学习的综述: 理论、方法与应用

摘要 为了应对现实世界的动态&#xff0c;智能系统需要在其整个生命周期中增量地获取、更新、积累和利用知识。这种能力被称为持续学习&#xff0c;为人工智能系统自适应发展提供了基础。从一般意义上讲&#xff0c;持续学习明显受到灾难性遗忘的限制&#xff0c;在这种情况下…

【Linux硬盘数据读取】WIN10访问linux分区解决方案:ext2fsd

<div id"content_views" class"htmledit_views" style"user-select: auto;"><p>尝试ext2explore、Paragon ExtFS都不好用&#xff0c;强烈安利ext2fsd&#xff0c;可读写&#xff0c;很强大</p> 转自&#xff1a;https://blog…

C++之模板(一)

1、为什么需要模板 将具有相同逻辑的一段代码提供一份模板&#xff0c;当我们需要处理不同类型的时候&#xff0c;可以通过数据类型当作参数来传递&#xff0c;从而实例化出对应类型的处理版本。 2、模板的定义 也是一种静态多态。 3、模板的分类 4、函数模板 5、函数模板的使…

-------------------------面试散文-----------------------------------

问题1&#xff1a;vue中动态引入图片&#xff0c;为什么使用require&#xff1f; 回答&#xff1a;因为动态添加的src 编译过后的文件地址和被编译过后的资源文件地址不一致&#xff0c;从而导致无法访问题 而使用require 返回的就是资源文件被编译后的文件地址&#xff0c;从…

Aeron:Aeron Agent

Aeron Agent 是一个 Java 代理&#xff0c;用于提供 Aeron、Aeron Archive 和 Aeron Cluster 中发生的运行时低级日志信息。这些日志语句包括从高级管理员事件到大容量数据帧事件。 在调试 Archive 和 Cluster 问题时&#xff0c;Aeron Agent 的日志数据尤其有用。 一、Availab…

本地无法连接linux上的MariaDB数据库

问题&#xff1a;本地用DBeaver无法连接服务器上的MariaDB数据库 &#xff1f; 测试1&#xff1a;在cmd中ping 服务器IP&#xff0c;看是否能ping通&#xff0c;能ping通&#xff0c;没有问题 测试2&#xff1a;在cmd中telnet 服务器IP 端口&#xff0c;看是否能访问&#xf…

常见的Redis使用问题及解决方案

目录 1. 缓存穿透 1.1 解决方案 2. 缓存击穿 2.1 解决方案 3. 缓存雪崩 3.1 概念图及问题描述 ​编辑3.2 解决方案 4. 分布式锁 4.1 概念 4.2 基于redis来实现分布式锁 4.3 用idea来操作一遍redis分布式锁 4.4 分布式上锁的情况下&#xff0c;锁释放了服务器b中的锁…

多态深度剖析

前言 继承是多态的基础&#xff0c; 如果对于继承的知识还不够了解&#xff0c; 可以去阅读上一篇文章 继承深度剖析 基本概念与定义 概念&#xff1a; 通俗来说&#xff0c;就是多种形态。具体点就是去完成某个行为&#xff0c; 当不同的对象去完成时会产生出不同的状…

如何完美解决 Xshell 使用 SSH 连接 Linux 服务器报错:找不到匹配的 host key 算法

&#x1f6e0;️ 如何完美解决 Xshell 使用 SSH 连接 Linux 服务器报错&#xff1a;找不到匹配的 host key 算法 摘要&#xff1a; 本文将带领大家深入学习如何解决 Xshell 使用 SSH 连接 Linux 服务器时报错“找不到匹配的 host key 算法”的问题。通过详细的操作步骤和代码案…

Shopee虾皮API:获取商家店铺商品列表

一、平台介绍 Shopee&#xff0c;作为东南亚及中国台湾地区领先的电商平台&#xff0c;为卖家提供了一个便捷、高效的销售渠道。作为卖家&#xff0c;能够将自己的商品展示在Shopee平台上&#xff0c;并通过平台的流量和工具&#xff0c;将商品销售给更多的潜在买家。 为了帮…

系统架构设计师 - 操作系统(2)

操作系统 操作系统&#xff08;5-6分&#xff09;文件管理绝对路径与相对路径 ★索引文件 ★★★位示图 ★ 存储管理段页式存储 ★★★页式存储段式存储段页式存储&#xff08;了解&#xff09; 页面置换算法 ★ 微内核操作系统嵌入式操作系统 ★★★ 大家好呀&#xff01;我是…

数据库课设-中小企业工资管理系统

一、效果展示 二、后端代码 import string import random from flask import Flask, render_template, request, jsonify, redirect, session import pymysql from flask_cors import CORS import time import schedule from datetime import datetime import threading from …

HK1-BOX X3刷UBUNTU 24.04,并开启WIFI

端午刚好有点时间&#xff0c;顺便把改完散热的HK1-BOX刷了个最新OC版的UBUNTU 24&#xff0c;这里记录下操作的步骤&#xff1a; 准备材料 HK1-BOX S905X3&#xff1a;注意X4的不行固件没匹配的。建议先改完散热&#xff0c;不然作为7X24小时的机器长时间高温还是很伤硬件的…