图形系统:简简单单学习WindowManagerService的启动流程

news2024/10/7 1:42:31

作者:新小梦

在系统启动流程中,Zygote进程通过fork自己来创建SystemServer进程。SystemServer进程的主要职责之一就是创建SystemServiceManger,使自己成为服务的注册中心,并启动三种不同类型的服务:引导服务、核心服务、其他服务。

WMS被划分到其他服务。我们以SystemServer的main函数为入口来分析WMS的启动流程。

1、SystemServer.main

public static void main(String[] args) {
    new SystemServer().run();
}

2、SystemServer.run

如下所见,SystemServer先加载android_servers动态库,创建SystemServiceManager对象,将服务划分为三种类型的服务引导服务、核心服务、其他服务。

private void run() {

    // 初始化本地服务
    System.loadLibrary("android_servers");
	...
    //创建系统服务管理
    mSystemServiceManager = new SystemServiceManager(mSystemContext);
	...
    //启动三种类型的服务
    try {
        startBootstrapServices(t);
        startCoreServices(t);
        startOtherServices(t);
    } catch (Throwable ex) {
        ...
    } finally {
        ...
    }
}

3、SystemServer.startOtherServices

startOtherServices函数会创建非常多的服务,这里重点关注WMS的创建,先创建了InputManagerService,再调用WindowManagerService的main函数。

...     
inputManager = new InputManagerService(context);
... 
wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore,
        new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
... 
ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
        DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
... 
//初始化PhoneWindowManager和添加WatchDog监听
wm.onInitReady();
...

wm.displayReady();
...
wm.systemReady();

4、WindowManagerService.main

    public static WindowManagerService main(final Context context, final InputManagerService im,
            final boolean showBootMsgs, final boolean onlyCore, WindowManagerPolicy policy,
            ActivityTaskManagerService atm, Supplier<SurfaceControl.Transaction> transactionFactory,
            Supplier<Surface> surfaceFactory,
            Function<SurfaceSession, SurfaceControl.Builder> surfaceControlFactory) {
        DisplayThread.getHandler().runWithScissors(() ->
                sInstance = new WindowManagerService(context, im, showBootMsgs, onlyCore, policy,
                        atm, transactionFactory, surfaceFactory, surfaceControlFactory), 0);
        return sInstance;
    }

DisplayThread继承自ServiceThread类,ServiceThread又继承自HandlerThread类。是一个前台系统共享的单例线程,主要服务于WindowManager、DisplayManager、InputManager快速实时执行显示相关的操作。

5、Handler.runWithScissors

public final boolean runWithScissors(@NonNull Runnable r, long timeout) {
    if (r == null) {
        throw new IllegalArgumentException("runnable must not be null");
    }
    if (timeout < 0) {
        throw new IllegalArgumentException("timeout must be non-negative");
    }

    if (Looper.myLooper() == mLooper) {
        r.run();
        return true;
    }

    BlockingRunnable br = new BlockingRunnable(r);
    return br.postAndWait(this, timeout);
}

当前代码是运行在SystemServer的主线程,runWithScissors函数使得Runable对象的run函数切换到DisplayThread代码执行。创建了BlockingRunnable类型的对象r,并调用其他postAndWait函数。此时参数timeout是0,this是自身Handler对象。

6、BlockingRunnable.postAndWait

//BlockingRunnable的postAndWait函数
public boolean postAndWait(Handler handler, long timeout) {
    if (!handler.post(this)) {//1
        return false;
    }

    synchronized (this) {
        if (timeout > 0) {
            while (!mDone) {
            	...
                try {
                    wait(delay);
                } catch (InterruptedException ex) {
                }
            }
        } else {
            while (!mDone) { //2
                try {
                    wait(); //3
                } catch (InterruptedException ex) {
                }
            }
        }
    }
    return true;
}
//BlockingRunnable的run函数,mTask是构造函数传递进来的Runable对象        
public void run() {
    try {
        mTask.run(); //4
    } finally {
        synchronized (this) {
            mDone = true; //5
            notifyAll();
        }
    }
}

注释1,由于handler对象来自DisplayThread线程,所以BlockingRunnable的run函数会在DisplayThread线程中执行。DisplayThread线程在执行注释4后,会执行注释5,将mDone设置为true,然后通知其他等待的线程继续执行。

注意到此时还运行在SystemServer线程中,当注释1的Runable对象添加到DisplayThread线程的Handler的消息队列会立即返回true,继续执行注释1后续代码。而不是等待DisplayThread线程执行完BlockingRunnable对象的run函数再返回。mDone变量默认false,执行到注释3代码时,如果mDone为true,SystemServer线程则不进入等待状态,代表DisplayThread已经执行完run函数,否则进入等待状态,直到DisplayThread线程执行完run函数通知SystemThread线程醒来继续执行。

总的来说就是,SystemServer线程会等待DisplayThread线程创建好WMS之后,再继续执行后续内容。到这里WindowMangerService对象也创建完毕。


WMS 是学习了解Framework底层原理的核心知识点之一,在Framework底层原理中除了WMS要学习以外,还有Binder、Handler、AMS、PMS……等知识点都要学习,这样才能全面的了解Framework底层原理,为了帮助大家可以更快速的掌握理解这个版块的知识点,这边整理了 《Framework 学习手册》,里面将其Framework中所有的知识点记录在册了,希望能给大家有效的帮助。

《Android Framework学习手册》:https://qr18.cn/AQpN4J

  1. 开机Init 进程
  2. 开机启动 Zygote 进程
  3. 开机启动 SystemServer 进程
  4. Binder 驱动
  5. AMS 的启动过程
  6. PMS 的启动过程
  7. Launcher 的启动过程
  8. Android 四大组件
  9. Android 系统服务 - Input 事件的分发过程
  10. Android 底层渲染 - 屏幕刷新机制源码分析
  11. Android 源码分析实战

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

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

相关文章

mqttx read econnreset异常排查

mqtt 会话 read econnreset 使用mqttx连接mqtt服务器时出现READ ECONNRESET的排查 前段时间公司新增了mqtt服务器&#xff0c;在我们初步测试的时候没有问题&#xff0c;但是随着连接数量增多&#xff0c;后续几天连续间隔出现READ ECONNRESET&#xff0c;导致项目无法正常使…

Unity Batching 批处理

Unity Batching 批处理 了解批处理前先了解下 Draw Call 要了解 Draw Call 需要先了解游戏引擎是如何把物体图像绘制到屏幕上的。 (1)&#xff1a;渲染流水线 渲染流水线的任务为从一个 二维、三维场景开始&#xff0c;最终渲染为一张二维图像&#xff0c;显示在屏幕上。 计算…

使用Unit Scaling进行FP16 和 FP8 训练

Unit Scaling 是一种新的低精度机器学习方法&#xff0c;能够在没有损失缩放的情况下训练 FP16 和 FP8 中的语言模型。 使用FP16和BFLOAT16替代FP32可以将内存、带宽和计算需求的大幅减少&#xff0c;这也是目前越来越大的模型所需要的。 背景介绍 随着支持fp8的硬件的发展&…

webrtc入门系列(三)云服务器coturn环境搭建

《webrtc入门系列&#xff08;一&#xff09;easy_webrtc_server 入门环境搭建》 《webrtc入门系列&#xff08;二&#xff09;easy_webrtc_server 入门example测试》 《webrtc入门系列&#xff08;三&#xff09;云服务器coturn环境搭建》 《webrtc入门系列&#xff08;四&…

测试题目气死人

服了差不多每一题都要错几个案例我真的服了wok&#xff0c;什么鬼东西&#xff01;&#xff01;&#xff01; lx学长的羊圈 Description lx学长是一个养羊大户&#xff0c;有成千上百个羊圈。可是却一次也没来羊圈帮过忙&#xff0c;今天他被叫来羊圈给羊羊们施展成双成对大法…

力扣算法系统刷题题解记录

力扣算法系统刷题题解记录 文章目录力扣算法系统刷题题解记录前言一、数组704二分查找示意图&#xff1a;解题思路代码27.移除元素示意图解题思路代码前言 参考顺序和资料&#xff1a;《代码随想录》 二刷要认真做笔记啦&#xff0c;加油&#xff01; 一、数组 704二分查找 …

2023-04-12 面试中常见的数组题目

数组中的问题其实最常见 通过基础问题&#xff0c;掌握写出正确算法的“秘诀”巧妙使用双索引技术&#xff0c;解决复杂问题对撞指针- 滑动窗口 1 从二分查找法看如何写出正确的程序 本节学习重点&#xff1a;处理边界问题&#xff01; 1.确定边界范围方法&#xff0c;先用区…

13、Qt生成dll-QLibrary方式使用

Qt创建dll&#xff0c;使用QLibrary类方式调用dll 一、创建项目 1、新建项目->其他项目->Empty qmake Project->Choose 2、输入项目名&#xff0c;选择项目位置&#xff0c;下一步 3、选择MinGW&#xff0c;下一步 4、完成 5、.pro中添加TEMPLATE subdirs&#xff…

定时任务之时间轮算法

初识时间轮 我们先来考虑一个简单的情况&#xff0c;目前有三个任务A、B、C&#xff0c;分别需要在3点钟&#xff0c;4点钟和9点钟执行&#xff0c;可以把时间想象成一个钟表。 如上图中所示&#xff0c;我只需要把任务放到它需要被执行的时刻&#xff0c;然后等着时针转到这个…

IP协议(网络层重点协议)

目录 一、IP协议报头格式 二、地址选择 1、IP地址 &#xff08;1&#xff09;格式 &#xff08;2&#xff09;组成 &#xff08;3&#xff09;分类 &#xff08;4&#xff09;子网掩码 三、路由选择 IP协议是网络层的协议&#xff0c;它主要完成两个方面的任务&#xf…

4.16--设计模式之创建型之代理模式(总复习版本)---脚踏实地,一步一个脚印

1.代理对象 定义&#xff1a;代理模式给某一个对象提供一个代理对象&#xff0c;并由代理对象控制对原对象的引用&#xff0c;从而实现对真实对象的操作。 通俗的来讲代理模式就是我们生活中常见的中介。 在代理模式中&#xff0c;代理对象主要起到一个中介的作用&#xff0c;…

初识Docker并在linux完成安装

文章目录一、 初识Docker1.1 简介1.2 Docker和虚拟机的异同1.3 Docker架构二、 DockerHub三、Docker的安装一、 初识Docker 1.1 简介 Docker是一种开源的容器化平台&#xff0c;可以让开发者在容器中打包、发布、运行和管理应用程序。它使用轻量级的容器来隔离应用程序和它们的…

Scrapy爬虫基本使用与股票数据Scrapy爬虫

Scrapy爬虫的常用命令 scrapy命令行格式 红色是常用的三种命令 为什么Scrapy采用命令行创建和运行爬虫&#xff1f; 命令行&#xff08;不是图形界面&#xff09;更容易自动化&#xff0c;适合脚本控制 本质上&#xff0c;Scrapy是给程序员用的&#xff0c;功能&#xff08…

vue打包之后,可以进行修改配置后端地址、端口等信息方法

前言 用vue-cli构建的项目通常是采用前后端分离的开发模式&#xff0c;也就是前端与后台完全分离&#xff0c;此时就需要将后台接口地址打包进项目中&#xff0c;但是&#xff0c;难道我们只是改个接口地址也要重新打包吗&#xff1f;当然不行了&#xff0c;那就太麻烦了&#…

支付宝沙箱环境+SpringBoot+内网穿透整合开发

目录 1.查看沙箱账号 2.内网穿透 3.沙箱环境整合SpringBoot开发 下面我将以实际案例详细介绍如何使用沙箱环境进行支付宝支付对接的开发 1.查看沙箱账号 首先什么是沙箱账号&#xff1f; 沙箱账号是指在支付宝沙箱环境中创建的测试账户&#xff0c;用于模拟真实的支付流程…

The 2022 ICPC Asia Xian Regional Contest

题目顺序大致按照难度排序。 F. Hotel 现在酒店中有单人间和双人间&#xff0c;价格分别是c1&#xff0c;c2&#xff0c;现在有n个队&#xff0c;每队三个人&#xff0c;性别分别用字母表示&#xff0c;当两个人性别相同且在同一个队时&#xff0c;他们可以住在双人间中。求最…

【跑跑Github开源项目系列】基于YOLO和Streamlit的车辆识别系统demo

【跑跑Github开源项目系列】基于YOLO和Streamlit的车辆识别系统demo写在前面环境配置创建虚拟环境安装库项目运行写在前面 相信很多朋友跟我一样在github等平台上偷代码 (读书人的事怎么能叫偷呢) 的时候会发现伟大且无私的作者虽然开源了代码但是readme文件该写的没写&#x…

2023TYUT移动应用软件开发程序设计和填空

目录 程序设计 程序设计1&#xff1a;根据要求设计UI,补充相应布局文件&#xff0c;即.xml文件 程序设计2&#xff1a;根据要求,补充Activity.java文件 程序填空 说明&#xff1a; 程序设计 程序设计1&#xff1a;根据要求设计UI,补充相应布局文件&#xff0c;即.xml文件…

【C++初阶】第十篇:list模拟实现

文章目录一、list的模拟实现三个类及其成员函数接口总览结点类的模拟实现迭代器类的模拟实现迭代器类的模板参数说明迭代器operator->的重载迭代器模拟实现代码list的模拟实现无参构造函数带参构造拷贝构造函数赋值运算符重载函数析构函数begin和endinserteraselist的迭代器…

WordPress添加阿里云OSS对象云储存配置教程

背景&#xff1a;随着页面文章增多&#xff0c;内置图片存储拖连网站响应速度&#xff0c;这里对我来说主要是想提升速度 目的&#xff1a;使用第三方云存储作为图片外存储(图床)&#xff0c;这样处理可以为服务器节省很多磁盘空间&#xff0c;在网站搬家的时候减少文件迁移的工…