Android的UI显示原理之Surface的创建

本文是基于Google Android Repo中的较新的源码分析的。Android UI渲染这一块变化还是比较大的,逻辑可能和网上大部分文章有一些出入。

在本文正式开始之前,我们先来了解一下与SurfaceFlinger相关的基础知识:

  • 与SurfaceFlinger相关的基础知识

SurfaceFlinger可以说是Android UI渲染体系的核心,在Android系统启动时会启动SurfaceFlinger服务,它的主要作用就是被Android应用程序调用,把绘制(测量,布局,绘制)后的窗口(Surface)渲染到手机屏幕上。所以整个
UI刷新过程可能像下面这张图:

 

当然实际上的UI渲染原理可没有像上图那样这么简单。为了接下来在源码追踪的过程中不迷路,我们带着下面几个问题来开始分析:

  1. WindowManagerService是如何管理Window的?
  2. Surface是如何创建的?
  3. SurfaceFlinger是如何管理多个应用的UI渲染的?
  4. SurfaceFlinger中UI渲染的基本单元是什么?

ok,接下来就开始Android UI显示原理之Surface的创建的主要流程分析。由于整个体系的源码流程很复杂,因此在追踪源码时我只贴了一些整个流程分析中的主要节点,并且加了一些注释。

在上一篇文章中我们知道,ViewRootImpl管理着整个view tree。
对于ViewRootImpl.setView(),我们可以简单的把它当做一个UI渲染操作的入口,因此我们就从这个方法开始看:

WindowManagerService对于Window的管理

ViewRootImpl.java

public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
    ...
    //mWindowSession是一个aidl,ViewRootImpl利用它来和WindowManagerService交互
    //mWindow是一个aidl,WindowManagerService可以利用这个对象与服务端交互
    //mAttachInfo可以理解为是一个data bean,可以跨进程传递
    res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
            getHostVisibility(), mDisplay.getDisplayId(), mWinFrame,
            mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
            mAttachInfo.mOutsets, mAttachInfo.mDisplayCutout, mInputChannel);
    ...
}

ViewRootImpl.setView()方法会向WindowManagerService请求添加一个Window,mWindowSession.addToDisplay()跨进程最终调用到了WindowManagerService.addWindow():

WindowManagerService.java

public int addWindow(Session session, IWindow client...) {
    ...
    //WindowState用来描述一个Window
    final WindowState win = new WindowState(this, session, client, token, parentWindow,
                appOp[0], seq, attrs, viewVisibility, session.mUid,
                session.mCanAddInternalSystemWindow);
    ...
    win.attach();  //会创建一个SurfaceSession

    mWindowMap.put(client.asBinder(), win); //mWindowMap是WindowManagerService用来保存当前所有Window新的的集合
    ...
    win.mToken.addWindow(win); //一个token下会有多个win state。 其实token与PhoneWindow是一一对应的。
    ...
}

WindowStateWindowManagerService用来描述应用程序的一个Window的对象。上面注释我标注了win.attach(),这个方法可以说是WindowSurfaceFlinger链接的起点,它最终会调用到Session.windowAddedLocked():

Session.java

void windowAddedLocked(String packageName) {
    ...
    if (mSurfaceSession == null) { 
        ...
        mSurfaceSession = new SurfaceSession();
        ...
    }
}

//SurfaceSession类的构造方法
public final class SurfaceSession {
    private long mNativeClient; // SurfaceComposerClient*

    public SurfaceSession() {
        mNativeClient = nativeCreate(); 
    }

这里调用了native方法nativeCreate(),这个方法其实是返回了一个SurfaceComposerClient指针。那这个对象是怎么创建的呢?

SurfaceComposerClient的创建

android_view_SurfaceSession.cpp

static jlong nativeCreate(JNIEnv* env, jclass clazz) {
    SurfaceComposerClient* client = new SurfaceComposerClient(); //构造函数其实并没有做什么
    client->incStrong((void*)nativeCreate);
    return reinterpret_cast<jlong>(client);
}

即构造了一个SurfaceComposerClient对象。并返回它的指针。这个对象一个应用程序就有一个,它是应用程序与SurfaceFlinger沟通的桥梁,为什么这么说呢?在SurfaceComposerClient指针第一次使用时会调用下面这个方法:

//这个方法在第一次使用SurfaceCo
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值