SurfaceFlinger是Android图像渲染的一个非常重要的模块。

文章目录

    • Android 系统启动流程
    • Window创建过程
      • 1.创建window
      • 2.setContentView()初始化DecorView
      • 3.WindowManager的创建
    • Window和View的添加
      • 1. ViewRootImpl初始化
      • 2. 关联ViewRootImpl和View
    • View的绘制
    • 总结

Android 系统启动流程

SurfaceFlinger学习之路(一)View的绘制流程_第1张图片
我们都知道,Android源自于Linux系统,由bootloader载入linux内核,从Linux内核Kernal启动init进程,解析init.rc文件。

创建Zygote进程:Android世界的开始。启动SystemServer进程,接收着其他进程请求创建负责fork新的子进程。

创建Service_Manager进程:Binder通信过程中的守护进程,本身也是一个Binder服务,提供了查询和注册binder服务。

创建SurfaceFlinger进程:负责接受多个进程来源的图像数据,合成并发送到显示设备。

Window创建过程

我们创建一个activity也会创建window,他是所有的view的载体。
SurfaceFlinger学习之路(一)View的绘制流程_第2张图片

在Activity的启动过程中,当Zygote 创建了一个新的进程之后执行了ActivityThread的main(),将走到ActivityThread的performLaunchActivity()。

// ActivityThread.javaprivate Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {    activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);  Application app = r.packageInfo.makeApplication(false, mInstrumentation);// 1. 创建window  activity.attach(...);    // 2. 调用oncreate()mInstrumentation.callActivityOnCreate(activity, r.state);}

1.创建window

performLaunchActivity反射实例化activity和创建Application。

调用了activity.attach()函数,内部创建了一个PhoneWindow

// Activity.javafinal void attach(...) {mWindow = new PhoneWindow(this);    // 3. 创建并设置WindowManager    mWindow.setWindowManager(...);}

2.setContentView()初始化DecorView

// Instrumentation.javapublic void callActivityOnCreate(Activity activity, Bundle icicle) {    prePerformCreate(activity);    activity.performCreate(icicle);    postPerformCreate(activity);}// Activity.javafinal void performCreate(Bundle icicle) {    onCreate(icicle);    ...}

往往我们都在会onCreate()中调用Activity的setContentView(),加载对应的布局文件。

// Activity.javapublic void setContentView(@LayoutRes int layoutResID) {    getWindow().setContentView(layoutResID);    ....}

其中getWindow()就是上面的PhoneWindow实例。最后交由PhoneWindow加载布局文件

// PhoneWindow.javapublic void setContentView(int layoutResID) {    installDecor();    ...    mLayoutInflater.inflate(layoutResID, mContentParent);}

phonewindow创建了window最顶层的DecorView,并加载对应的布局文件;

我们都知道Activity只有到onResume()才是真正显示了;

此时,View还是没有渲染,Window也还没被添加。

3.WindowManager的创建

Android的WindowManager和View、Window可以参考《WindowManagerService Window View 关系(一)》

在这里是创建了WindowManagerImpl实例,借助他来管理Window、DecorView、ViewRootImpl三者的关系,并通过Session跟WMS通信。

// WindowManager.javapublic void setWindowManager(WindowManager wm, IBinder appToken, String appName,    boolean hardwareAccelerated) {    if (wm == null) {        wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);    }    mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);}// WindowManagerImpl.javapublic WindowManagerImpl createLocalWindowManager(Window parentWindow) {    return new WindowManagerImpl(mDisplay, parentWindow);}

Window和View的添加

后续,ActivityThread会走到handleResumeActivity()

// ActivityThread.javafinal void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, boolean reallyResume) {    r.window = r.activity.getWindow();    View decor = r.window.getDecorView();    decor.setVisibility(View.INVISIBLE);    ViewManager wm = a.getWindowManager();    WindowManager.LayoutParams l = r.window.getAttributes();    a.mDecor = decor;    ...    wm.addView(decor, l);}

wm对应上面的WindowManagerImpl,我们都知道事实上WindowManagerImpl是个装饰类。

WindowManagerGlobal执行添加View:addView(),内部做了很多事情。

// WindowManagerGlobal.javapublic void addView(View view, ViewGroup.LayoutParams params,            Display display, Window parentWindow) {    ViewRootImpl root;    // 1. ViewRootImpl初始化    root = new ViewRootImpl(view.getContext(), display);        mViews.add(view);    mRoots.add(root);        // 2. 关联ViewRootImpl、View    root.setView(view, wparams, panelParentView);}

ViewRootImpl是一个非常重要的类,ViewRootImpl,它在View的绘制发挥重要的作用,所有View的绘制以及事件分发等交互都是通过它来执行或传递的。

可参考《View/ViewGroup 绘制流程和疑惑》;

1. ViewRootImpl初始化

本文只注重ViewRootImpl跟Window、View绘制方面的关系,但是ViewRootImpl并不止于绘制方面,还负责了input event等事件的处理,这里先不做讨论。

//ViewRootImpl.javafinal Surface mSurface = new Surface();public ViewRootImpl(Context context, Display display) {    // 1.创建WindowSession,是binder的client端,方便调用WMS的服务    mWindowSession = WindowManagerGlobal.getWindowSession();    // 2.创建W,是binder的service端,支持被WMS调用ViewRootImpl    mWindow = new W(this);    // 3.创建编舞者    mChoreographer = Choreographer.getInstance();}

mWindowSession 是 WMS创建的一个Session,提供给ViewRootImpl调用WMS的服务。

// WindowManagerService.java public IWindowSession openSession(...) {    Session session = new Session(this, callback, client, inputContext);    return session; }

Session 在后面会发挥重要的作用。WMS会为App创建一个Session,App利用Session跟WMS跨进程通信。

Surface是Android提供给上层Activity绘制的一个界面,表面上我们绘制的是View,最后会绘制到Surface,每一个窗口都会有一个Surface。

new Surface()只是创建了一个空的Surface,之后copyFrom()才会真正填充surface。下一节再继续讲述Surface的真正创建。

// Surface.javapublic Surface() {}

我们在调用requestLayout()或者invalidate(),ViewRootImpl并不是马上就开始绘制,得等到一个时机才会执行绘制的三大流程:measure()、layout()、draw();而Choregrapher就是控制什么时候执行绘制流程。

mChoregrapher是编舞者,负责控制ViewRootImpl绘制时机,跟Vsync同步信号相关。

具体可以参考《Android 屏幕刷新机制:ViewRootImpl、Choreographer、Surface、SurfaceFlinger关系》

2. 关联ViewRootImpl和View

前面WindowManagerGlobal的setView(),调用了ViewRootImpl.addView()关联了View、ViewRootImpl

public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {    mView = view;    ...    res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,        getHostVisibility(), mDisplay.getDisplayId(), mWinFrame,        mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,        mAttachInfo.mOutsets, mAttachInfo.mDisplayCutout, mInputChannel);    ...}

ViewRootImpl 借助了上面mWindowSession跟WMS跨进程通信。我们看下binder的服务端Session做了什么工作。

WindowManagerService 真正实现添加一个Window。

// Session.javapublic int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs,    int viewVisibility, int displayId, Rect outFrame, Rect outContentInsets,    Rect outStableInsets, Rect outOutsets, DisplayCutout.ParcelableWrapper outDisplayCutout,     InputChannel outInputChannel) {    // mService就是WindowManagerService    return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId, outFrame,       outContentInsets, outStableInsets, outOutsets, outDisplayCutout, outInputChannel);}// WindowManagerService.javapublic int addWindow(Session session, IWindow client, ...) {     ...     final WindowState win = new WindowState(...);     win.attach();}// WindowState.javavoid attach() {    mSession.windowAddedLocked(mAttrs.packageName);}// Session.javavoid windowAddedLocked(String packageName) {    if (mSurfaceSession == null) {        mSurfaceSession = new SurfaceSession();        mService.mSessions.add(this);    }}

上述的过程追溯下来就是想说明,WMS添加Window的过程中,Session最后会创建SurfaceSession,而SurfaceSession是什么呢??

通过上面我们知道,每一个窗口在WMS中会有一个对应的Session,而一个Session会创建对应的SurfaceSession,SurfaceSession的作用就是负责跟SurfaceFlinger通信。

后续我们会看到SurfaceSession,发挥怎样的作用。

View的绘制

以上,我们讲述了Window、View、ViewRootImpl、WindowManagerImpl、WMS、Session、SurfaceSession之间大概是怎么样的关系。

View的绘制应该从ViewRootImpl的performTraversal()讲起。下面我们讲,View的绘制流程,但是这里不讲述View的三大绘制历程。

首先我们知道View的绘制都是从ViewRootImpl.performTraversals()讲起。

// ViewRootImpl.javaprivate void performTraversals() {    relayoutWindow(params, viewVisibility, insetsPending);     performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);    performLayout(lp, mWidth, mHeight);    performDraw();}

relayoutWindow表示让WMS重新布局画布,后续WMS才会给Surface设置属性或者创建新的Surface。

// ViewRootImpl.javaprivate int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,    boolean insetsPending) {    ...int relayoutResult = mWindowSession.relayout(...);}//Session.javapublic int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs,    int requestedWidth, int requestedHeight, int viewFlags, int flags, long frameNumber,    Rect outFrame, Rect outOverscanInsets, Rect outContentInsets, Rect outVisibleInsets,    Rect outStableInsets, Rect outsets, Rect outBackdropFrame,    DisplayCutout.ParcelableWrapper cutout, MergedConfiguration mergedConfiguration, Surface outSurface) {    int res = mService.relayoutWindow(...);    return res;}

后面文章继续讲WMS.relayoutWindow()、SurfaceSession…关系等。

总结

SurfaceFlinger学习之路(一)View的绘制流程_第3张图片

更多相关文章

  1. Phone拨号调起InCallUi流程(Phone 9.0 )(Phone调用InCallUi流程)
  2. 使用AIDL实现Android的跨进程通信
  3. android跨进程通信(IPC):使用AIDL
  4. Android启动流程分析(十二) SystemServer
  5. Android获得全局进程信息以及进程使用的内存情况
  6. android Aidl 实现进程间通讯
  7. FregServer进程,获取ServiceManager代理对象

随机推荐

  1. Android(安卓)开发之 ---- bootloader (LK
  2. Android(安卓)Things | 用Android玩转物
  3. Android(安卓)6.0权限获取方式-shouldSho
  4. Android(安卓)通过无线调试
  5. ObjectHttp使用介绍篇 —— 基础使用
  6. android studio 框架搭建:加入注解框架Ann
  7. Android基础控件——EditText隐藏软键盘
  8. Android(安卓)常用开发类库
  9. 如何实现一个图片加载框架
  10. flutter的AndroidX版本适配