Android ViewRootImpl源码分析

文章目录

Android ViewRootImpl源码分析

概述

ViewRootImpl 是连接 View 层和 WindowManagerServcie(WMS) 的桥梁。

作用:

  • 负责管理整个 View 树的布局、测量、绘制流程
  • 负责与 WMS 通信,完成窗口的添加、更新、移除
  • 调度 InputEventReceiver,处理输入事件、焦点变化等。

流程

ActivityThread.handleLaunchActivity():

  1. Instrumentation.newActivity()
  2. Instrumentation.callActivityOnCreate()
  3. Activity.performCreate()
  4. Activity.onCreate()
  5. Activity.setContentView()

ActivityThread.handleResumeActivity():

  1. ActivityThread.performResumeActivity():
    1. Activity.performResume()
    2. Instrumentation.callActivityOnResume()
    3. Activity.onResume()
  2. Activity.makeVisible():
    1. WindowManagerImpl.addView()
    2. WindowManagerGlobal.addView():创建ViewRootImpl实例,并关联ViewRootImpl和DecorView
    3. ViewRootImpl.setView()
    4. ViewRootImpl.requestLayout()
    5. ViewRootImpl.scheduleTraversals()
    6. ViewRootImpl.doTraversal()
    7. ViewRootImpl.performTraversals()
    8. ViewRootImpl.performMeasure():测量流程
    9. ViewRootImpl.performLayout():布局流程
    10. ViewRootImpl.performDraw():绘制流程

源码分析

ActivityThread.handleResumeActivity()

java 复制代码
public void handleResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
        boolean isForward, boolean shouldSendCompatFakeFocus, String reason) {
    // Activity的状态由可见转变为可见可交互
    // 依次调用:ActivityThread.performResumeActivity() → Activity.performResume() → Instrumentation.callActivityOnResume() → Activity.onResume()
    if (!performResumeActivity(r, finalStateRequest, reason)) {
        return;
    }
    
    // 调用Activity.makeVisible()
    r.activity.makeVisible();
}

Activity.makeVisible()

java 复制代码
void makeVisible() {
    if (!mWindowAdded) {
        ViewManager wm = getWindowManager();
        // 代理转发,实际由WindowManagerImpl处理,并传入DecorView
        wm.addView(mDecor, getWindow().getAttributes());
        mWindowAdded = true;
    }
    mDecor.setVisibility(View.VISIBLE);
}

WindowManagerImpl.addView()

java 复制代码
@Override
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
    applyTokens(params);
    // 调用WindowManagerGlobal.addView()
    mGlobal.addView(view, params, mContext.getDisplayNoVerify(), mParentWindow,
            mContext.getUserId());
}

WindowManagerGlobal.addView()

java 复制代码
public void addView(View view, ViewGroup.LayoutParams params,
                    Display display, Window parentWindow, int userId) {     
    final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;
    ViewRootImpl root;
    View panelParentView = null;

    synchronized (mLock) {

        // 创建ViewRootImple实例
        if (windowlessSession == null) {
            root = new ViewRootImpl(view.getContext(), display);
        } else {
            root = new ViewRootImpl(view.getContext(), display,
                                    windowlessSession, new WindowlessWindowLayout());
        }

        // DecorView设置布局参数
        view.setLayoutParams(wparams);

        // ViewRootImple关联DecorView
        root.setView(view, wparams, panelParentView, userId);
    }
}

ViewRootImpl.setView()

java 复制代码
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView,
        int userId) {
    synchronized (this) {
        if (mView == null) {
            // 保存DecorView
            mView = view;

            // 请求布局
            requestLayout();
             
            // 通过IBinder向WMS申请窗口和画布
            res = mWindowSession.addToDisplayAsUser(mWindow, mWindowAttributes,
                        getHostVisibility(), mDisplay.getDisplayId(), userId,
                        mInsetsController.getRequestedVisibleTypes(), inputChannel, mTempInsets,
                        mTempControls, attachedFrame, compatScale);
            
            // 绑定父子关系,将DecorView的父容器设置为ViewRootImpl
            view.assignParent(this);
    }
}

ViewRootImpl.requestLayout()

java 复制代码
@Override
public void requestLayout() {
    if (!mHandlingLayoutInLayoutRequest) {
        checkThread();
        mLayoutRequested = true;
        // 调度遍历流程
        scheduleTraversals();
    }
}

ViewRootImpl.scheduleTraversals()

java 复制代码
void scheduleTraversals() {
    if (!mTraversalScheduled) {
        mTraversalScheduled = true;
        mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
        // 插入同步屏障, 最终调用doTraversal()
        mChoreographer.postCallback(
            Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
        notifyRendererOfFramePending();
        pokeDrawLockIfNeeded();
    }
}

final TraversalRunnable mTraversalRunnable = new TraversalRunnable();

final class TraversalRunnable implements Runnable {
    @Override
    public void run() {
        doTraversal();
    }
}

ViewRootImpl.doTraversal()

java 复制代码
void doTraversal() {
    if (mTraversalScheduled) {
        mTraversalScheduled = false;
        mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier);

        if (mProfile) {
            Debug.startMethodTracing("ViewAncestor");
        }
	
        // 绘制流程
        performTraversals(); 
    }
}

ViewRootImpl.performTraversals()

java 复制代码
private void performTraversals() {
    // 测量阶段
    performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
    
    // 布局阶段
    performLayout(lp, mWidth, mHeight);   

    // 绘制阶段
    performDraw(mActiveSurfaceSyncGroup)
}
相关推荐
知行合一。。。4 小时前
Python--05--面向对象(属性,方法)
android·开发语言·python
leobertlan4 小时前
好玩系列:用20元实现快乐保存器
android·人工智能·算法
代龙涛7 小时前
WordPress single.php 文章模板开发详解
android
YF02119 小时前
Flutter 编译卡顿解决方案
android·flutter·ios
空中海10 小时前
第十二章:安卓实战架构与最佳实践
android·架构
angerdream11 小时前
Android手把手编写儿童手机远程监控App之四大组件详解2
android
kerli11 小时前
基于 kmp/cmp 的跨平台图片加载方案 - 适配 Android View/Compose/ios
android·前端·ios
半条-咸鱼13 小时前
基于安卓的 WAV 音频采集方案_含工具
android·音视频
九皇叔叔13 小时前
MySQL8.0 版本安装部署
android·adb