jargon explain - mehome/openthos GitHub Wiki

术语列表

Activity 相关

  • AM:ActivityManager

  • AMS:ActivityManagerService,主要负责处理对android四大组件的管理和响应Client端的请求。此外还包括进程的产生和对WindowManagerService的操作。

  • ActivityThread,App的真正入口。当开启App之后,会调用main()开始运行,开启消息循环队列,这就是传说中的UI线程或者叫主线程。与ActivityManagerServices配合,一起完成Activity的管理工作

  • ApplicationThread,用来实现ActivityManagerService与ActivityThread之间的交互。在ActivityManagerService需要管理相关Application中的Activity的生命周期时,通过ApplicationThread的代理对象与ActivityThread通讯。

  • ApplicationThreadProxy,是ApplicationThread在服务器端的代理,负责和客户端的ApplicationThread通讯。AMS就是通过该代理与ActivityThread进行通信的。

  • Instrumentation,每一个应用程序只有一个Instrumentation对象,每个Activity内都有一个对该对象的引用。Instrumentation可以理解为应用进程的管家,ActivityThread要创建或暂停某个Activity时,都需要通过Instrumentation来进行具体的操作。

  • ActivityStack,Activity在AMS的栈管理,用来记录已经启动的Activity的先后关系,状态信息等。通过ActivityStack决定是否需要启动新的进程。

  • ActivityRecord,ActivityStack的管理对象,每个Activity在AMS对应一个ActivityRecord,来记录Activity的状态以及其他的管理信息。其实就是服务器端的Activity对象的映像。

  • Task:是指一系列Activity的集合,这些Activity就可以看成是一个任务。这些Activity可以属于同一个App,也可以属于不同的App。

  • TaskRecord,AMS抽象出来的一个“任务”的概念,是记录ActivityRecord的栈,一个“Task”包含若干个ActivityRecord。AMS用TaskRecord确保Activity启动和退出的顺序。如果你清楚Activity的4种launchMode,那么对这个概念应该不陌生。

  • ProcessRecord: Full information about a particular process that is currently running. (framework/base/services/core/java/com/android/server/am/ProcessRecord.java)

Window相关

  • WM:WindowManager
  • WMS:WindowManagerService
  • ViewManager这个接口里面就三个接口,添加、移除和更新,实现这个接口的有WindowManager和ViewGroup,但是他们两个面向的对象是不一样的,WindowManager实现的是对Window的操作,而ViewGroup则是对View的增、删、更新操作。
  • WindowManagerImpl是WindowManager的实现类,但是他就是一个代理类,代理的是WindowManagerGlobal,WindowManagerGlobal一个App里面就有一个,因为它是单例的,它里面管理了App中所有打开的DecorView,ContentView和PhoneWindow的布局参数WindowManager.LayoutParams,而且WindowManagerGlobal这个类是和WMS通信用的,是通过IWindowSession对象完成这个工作的,而IWindowSession一个App只有一个,但是每个ViewRootImpl都持有对IWindowSession的引用,所以ViewRootImpl可以和WMS喊话,但是WMS怎么和ViewRootImpl喊话呢?是通过ViewRootImpl::W这个内部类实现的,而且源码中很多地方采用了这种将接口隐藏为内部类的方式,这样可以实现六大设计原则之一——接口最小原则,这样ViewRootImpl和WMS就互相持有对方的代理,就可以互相交流了
  • WindowSession: (IWindowSession.aidl) System private per-application interface to the window manager:也就是说每个App进程都会和WMS建立一个IWindowSession会话。这个会话被App进程用于和WMS通信。
  • Window: (IWindow.aidl) API back to a client window that the Window Manager uses to informit of interesting things happening:这句话的大意是IWindow是WMS用来做事件通知的。每当发生按键、触屏等事件时,WMS就会把这些事告诉某个IWindow。可以把IWindow想象成一个回调函数。WMS所在的SystemServer进程接收到按键事件。一个按键事件被分发的大致的流程: (1) WMS找到UI位于屏幕顶端的进程所对应的IWindow对象,这是一个Bp端对象。(2) 调用这个IWindow对象的dispatchKey。(3)IWindow对象的Bn端位于ViewRoot中,ViewRoot再根据内部View的位置信息找到真正处理这个事件的View,最后调用dispatchKey函数完成按键的处理。
  • ViewRootImpl: ViewRootImpl这个类每个Activity都有一个,它负责和WMS通信,同时相应WMS的指挥,还负责View界面的测量、布局和绘制工作,所以当你调用View.invalidate()和View.requestLayout()的时候,都会把事件传递到ViewRootImpl,然后ViewRootImpl计算出需要重绘的区域,告诉WMS,WMS再通知其他服务完成绘制和动画等效果.与WMS交互是通过WindowSession。而且ViewRootImpl也负责UI界面的布局与渲染,负责把一些事件分发至Activity,以便Activity可以截获事件。大多数情况下,它管理Activity顶层视图DecorView,它相当于MVC模型中的Controller。Window中有几个视图相关的比较重要的成员变量如下所示:
  • mDecor:DecorView的实例,标示Window内部的顶级视图
  • mContentParent:setContetView所设置的布局文件就加到这个视图中
  • mContentRoot:是DecorView的唯一子视图,内部包含mContentParent,标题栏和状态栏。
  • WindowManagerGlobal: 是单例模式,所以在一个App里面只会有一个WindowManagerGlobal实例。在WindowManagerGlobal里面维护了三个集合,分别存放添加进来的View(实际上就是DecorView),布局参数params,和刚刚实例化的ViewRootImpl对象. 其实,WindowManagerGlobal是和WindowManagerService(即WMS)通信的。
  • WMS和app的接口:双方都有了对方的接口,WMS中的Session注册到WindowManagerGlobal的成员WindowSession中,ViewRootImpl::W注册到WindowState中的成员mClient中。前者是为了App改变View结构时请求WMS为其更新布局。后者代表了App端的一个添加到WMS中的View,每一个像这样通过WindowManager接口中addView()添加的窗口都有一个对应的ViewRootImpl,也有一个相应的ViewRootImpl::W。它可以理解为是ViewRootImpl中暴露给WMS的接口,这样WMS可以通过这个接口和App端通信。

画图需要的四要素:

  • Bitmap:用于存储像素,也就是画布。可把它当做一块数据存储区域。

  • Canvas:用于记载画图的动作,比如画一个圆,画一个矩形等。Canvas类提供了这些基本的绘图函数。

  • Drawing primitive:绘图基元,例如矩形、圆、弧线、文本、图片等。

  • Paint:它用来描述绘画时使用的颜色、风格(如实线、虚线等)等。

  • RGB565:表示一个像素点中R分量为5位,G分量为6位,B分量为5位,并且没有Alpha分量。

  • RGB888:一个像素是一个字节,共3个字节。

  • PageFlipping: 中文名叫画面交换,其操作过程如下所示:(1) 分配一个能容纳两帧数据的缓冲,前面一个缓冲叫FrontBuffer,后面一个缓冲叫BackBuffer。(2) 消费者使用FrontBuffer中的旧数据,而生产者用新数据填充BackBuffer,二者互不干扰。(3) 当需要更新显示时,BackBuffer变成FrontBuffer,FrontBuffer变成BackBuffer。如此循环,这样就总能显示最新的内容了。这个过程很像我们平常的翻书动作,所以它被形象地称为PageFlipping。

FrameBufferDevice:

  • FrameBuffer 就是存储图像帧数据的缓冲区;

  • FrameBufferDevice 是 Linux 平台的虚拟显示设备,为真实设备提供统一框架,这样应用层通过标准的 ioctl 、 mmap 系统调用就可以操作显示设备;

  • FrameBuffer 中的缓冲区就是通过 mmap 把设备中的显存映射到用户空间的:在这块缓冲区写数据,就相当于在屏幕上绘制;

Window 和 View:

  • Window 是抽象基类,用于控制顶层窗口的外观和行为(背景、标题栏、默认按键处理等);

  • View 是基本的 UI 单元,占据屏幕一块矩形区域,用于绘制和事件处理;

ViewRoot:

  • ViewRoot 继承自 Handler (可处理消息),并实现了 ViewParent 接口(不处理绘制、没有 onDraw() );

  • ViewRoot 内部有一个 IWindow.Stub 对象(用于 Binder 通信)、 View 对象和 Surface 对象(用于 View 绘制,有一块 Raw buffer,可以和 SurfaceFlibger 交互);

  • ViewRoot 构造方法调用 getWindowSession() 将 ViewRoot 和 WindowManagerService 关联起来;

  • ViewRoot::setView() :

  1. 将传入的 View 指向 PhoneWindow 的 DecorView ;

  2. 调用 requestLayout() , 向 Handler 发送 DO_TRAVERSAL 消息; 收到消息后调用 IWindowSession 的 relayout() ,

  3. 调用 draw() ,先从 Surface 中 lock 一块 Canvas ,然后让 View 绘制,最后调用 unlockCanvasAndPost() ;

  4. 调用 IWindowSession的add() 方法,这是一个跨进程的 Binder 通信;

  • ViewRoot 与其子 View 共用一个 Canvas ,但 lockCanvas() 得到的内存不同;它们一般也共用一个 Surface ( SurfaceView 除外,它在单独线程绘制);

Activity 的创建:

  1. Activity 主线程 ActivityThread 类的 handleLaunchActivity() 方法用于创建 Activity ;

  2. 用 ClassLoader 和反射创建 Activity 对象,并调用其 onCreate() ;

  3. 调用 Activity 的 attach() 方法,内部调用 PolicyManager 的 makeNewWindow() 方法创建 PhoneWindow 对象;

  4. 调用 setWindowManager() ,创建 LocalWindowManager 对象,内部保存 WindowManager 对象,而其实际类型为 WindowManagerImpl ;

  5. setContentView() 设置的 View 其实是 DecorView 的子 View ; DecorView 是 FrameLayout 类型的 ViewGroup ,处理了标题栏显示等工作;

  6. LocalWindowManager 的 addView() 方法内部创建了 ViewRoot 对象;

WindowManagerService:

  • openSession() :创建内部类 Session 对象,可用于响应 Binder 通信中的请求;

  • addWindow() : 创建 WindowState 和 SurfaceSession 对象,窗口数 mNumWindow 自增;

  • relayoutWindow() :

  1. 先创建本地 Surface ,并分别调用 Surface.openTransaction() 和 closeTransaction() 进行事务处理;

  2. 调用 Surface 的 copyFrom() 拷贝本地 Surface 的信息;

  3. 调用 Surface 的 writeToParcel() 写入数据;

  • 对按键事件的分发:
  1. WMS 所在的 SystemServer 进程接收到事件;

  2. WMS 找到 UI 位于屏幕顶端的进程所对应的 IWindow 对象;

  3. 调用 IWindow 对象的 dispatchKey() 分发事件;

  4. ViewRoot 找到真正处理该事件的 View ,并调用其 dispatchKey() ;

Java 层 Surface:

  • 无参构造方法:创建一个 CompatibleCanvas 对象,而 Canvas 一般会封装一个 Bitmap 对象用于绘制;

  • 有参构造方法:

  1. 创建一个 CompatibleCanvas 对象,并调用本地 init() 方法;

  2. 创建一个 SurfaceComposerClient ,并调用其 createSurface() 函数得到 SurfaceControl 对象;

  3. 调用 SurfaceControl 对象的 writeSurfaceToParcel() 把数据写入 Parcel 包;

  4. 根据 Parcel 包构造一个 Surface 对象,并保存到 Java 层,这样 ViewRoot 就得到一个 Native 的 Surface 对象;

  • lockCanvas() :
  1. 取到 Native 的 Canvas 对象,并根据 dirtyRect (需要重绘的矩形区域)创建 Region 对象;

  2. 调用 Native 层 Canvas 的 lock() 函数;

  3. 取出 Java 层的 CompatibleCanvas 对象,给 Bitmap 指定存储区域,并将 Bitmap 和 Canvas 绑定;

Native 层 Surface:

  • 构造函数:定义 GraphicBuffer 数组,读取 Parcel 中的数据,创建 SurfaceComposerClient 对象;

  • lock() :

  1. 设置 usage 标志,用于 GraphicBuffer 分配缓冲;

  2. 调用 dequeueBuffer() :调用 SharedBufferClient 的 dequeueBuffer() ,并调用 Layer 的 requestBuffer() 得到 GraphicBuffer ;

  3. 调用 lockBuffer() :调用 SharedBufferClient 的 lock() ;

  4. 调用 copyBlt() :把 FrontBuffer(mPostedBuffer) 中的旧数据拷贝回 BackBuffer(叠加后防止重复绘制);

  5. unlockAndPost() :返回 GraphicBuffer 编号,调用 queueBuffer() ,设置 DirtyRegion,更新写位置;

SurfaceComposerClient:

  • SurfaceComposerClient 建立了和 SurfaceFlinger 交互的通道:构造函数会调用 SurfaceFlinger 的 createConnection() 创建连接;

  • 初始化时会创建 BpSurfaceFlinger 类型的 mSignalServer 对象,用于在客户端更新 BackBuffer 后通知 SurfaceFlinger 进行 PageFlipping 和输出;

  • createSurface() :创建 ISurface 对象,并以其为参数创建 SurfaceControl 对象(封装了一些函数,可以方便地调用 SurfaceComposerClient 和 ISurface 提供的函数);

  • openTransaction() :主要是用 AutoLock 控制计数变量 mTransactionOpen 自增;

  • setPosition() :修改控制 Surface 在屏幕上的位置和宽高信息的 layer_state_t ;

  • closeGlobalTransaction() :

  1. 先调用 SurfaceFlinger.openGlobalTransaction() :也是一个计数控制;

  2. 然后调用 SurfaceFlinger.setClientState() :遍历所有 Layer ,调用其 setPosition() ,最后设置 flag ;

  3. 最后调用 SurfaceFlinger.closeGlobalTransaction() :调用 siginalEvent() 提交事务;

SurfaceFlinger:

  • SurfaceFlinger 驻留于 system_server 进程,是从 Thread 派生的,会单独启用一个工作线程;

  • onFirstRef() :

  1. 第一次创建引用时调用;

  2. 首先启用工作线程,然后调用 Barrier (封装了 Mutex 和 Condition 的同步类)的 wait() ;

  • createConnection() :
  1. 创建 Client ,并保存到 ClientsMap , Client 内部会创建一块共享内存 MemoryHeapBase ,以及用于读写控制的 SharedClient 对象;

  2. 根据 Client 创建用于 Binder 通信的 BClient , BClient 派生于 ISurfaceFlingerClient ,用于接收客户端请求,并提交给 SurfaceFlinger ;

  3. createSurface() : 根据传入的 flag 创建 PushBuffer / Normal / Blur / Dim 等不同类型的显示层( LayerBaseClient );

  • readyToRun() :
  1. 创建 GraphicPlane (目前只支持一块屏幕),并设置 HAL 对象 DisplayHardware ;

  2. 创建共享内存 MemoryHeapBase ;

  3. 获取屏幕信息,调用 OpenGL 相关函数;

  4. 调用 Barrier.open() 触发同步条件;

  5. 调用 property_set 设置 boot 动画;

  • SurfaceFlinger 创建 FrameBuffer ,并将各个 Surface 传输的数据通过 GraphicBuffer 混合后,再由自己传输到 FrameBuffer ;

  • threadLoop() 线程循环:

  1. 调用 waitForEvent() :等待 INVALIDATE 重绘消息( unlockCanvasAndPost() 会调用 signal() ,进而调用 mEventQueue.invalidate() );

  2. 调用 handleTransaction() :调用 handleTransactionLocked() 处理事务,调用每个 Layer.ditch() 丢弃被 hide 的层;

  3. 调用 handlePageFlip() :调用 Layer.lockPageFlip() 根据 FrontBuffer 数据生成 Texture;调用 Layer.unlockPageFlip() 做清理工作;

  4. 调用 handleRepaint() :获取 DisplayHardware ,计算 DirtyRegion;按 Z 轴顺序由里到外依次调用 Layer.draw() 函数;

  5. 调用 unlockClients() :调用 Layer.unlock(mFrontBufferIndex) ,释放占用的 FrontBuffer;

  6. 调用 postFrameBuffer() :调用 DisplayHardware.flip() ,交换 buffer,使图像显示;

  • handleTransactionLocked() 事务处理:
  1. 获得所有显示层数组 layersSortedByZ ;

  2. 如需要遍历,则调用所有 Layer.onTransaction() ;

  3. 处理横竖屏切换和 layersRemoved ;

  4. 调用 commitTransaction() :调用同步变量的 broadcast() 函数;

SharedClient 与 SharedBuffer 家族:

  • 每个 SurfaceFlinger 内部定义一个跨进程共享的 SharedClient ;

  • SharedClient 内部的 SharedBufferStack 数组有 31 个元素,对应 31 个显示层,每层的读写步调由 SharedBufferStack 内部的成员变量控制;

  • SharedBuffer 家族在 SurfaceFlinger 端的代表是 SharedBufferServer , 在 Activity 端的代表是 SharedBufferClient ;

LayerBaseClient:

  • LayerBaseClient 继承自 LayerBase ,且有四个派生类: Layer 、 LayerBuffer 、 LayerDim 、 LayerBlur ;

  • LayerBaseClient 定义了内部类 Surface ,它继承自 ISurface ,支持 Binder 通信;

  • 构造函数:使用 SharedClient 对象创建 SharedBufferServer 对象;

  • setBuffs() :创建用于 PageFlipping 的两个 GraphicBuffer 对象:FrontBuffer 和 BackBuffer;

  • addLayer_l() :把新创建的 Layer 加入自己的 Z 轴 Layer 数组: layersSortedByZ ;

  • onDraw() : 调用 OpenGL 相关函数绘制;

GraphicBuffer:

  • 是Surface系统中一个高层次的显示内存管理类,它封装了和硬件相关的一些细节,简化了应用层的处理逻辑。

  • 继承自 LightRefBase 使它支持引用计数;

  • 继承自 Flattenable 使它支持序列化和反序列化,可封装于 Parcel 中用于 Binder 通信:

  1. 响应端 BnSurface 的 onTransact() 方法中 reply.write(*buffer) 会触发 flatten() 序列化;

  2. 请求端 BpSurface 的 requestBuffer 中 reply.read(*buffer) 会触发 unflatten() 反序列化;

  • GraphicBufferAllocator: 内部的 GraphicBufferAllocator 对象用于内存分配;GraphicBuffer的存储分配和GraphicBufferAllocator有关。 ./frameworks/native/libs/ui/GraphicBufferAllocator.cpp