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)
}
相关推荐
Yang-Never2 小时前
ADB ->Android 实时监控内存
android·开发语言·adb·android studio
zhangren024682 小时前
Laravel5.x版本特性全解析
android·vue.js·spring boot·mysql
2501_915918412 小时前
WebKit 抓包,WKWebView 请求的完整数据获取方法
android·前端·ios·小程序·uni-app·iphone·webkit
EasyControl移动设备管理2 小时前
打破系统壁垒:从 Android 到 macOS,打造全平台统一终端管理(MDM)方案
android·人工智能·物联网·macos·移动设备管理·mdm系统·跨区域设备
帅得不敢出门3 小时前
Android Framework中调用由java编译成的jar接口
android·java·framework·jar
火山上的企鹅3 小时前
QGC 二次开发实战:Android 单机离线授权怎么落地
android·qt·qgroundconrol·离线授权
黄林晴3 小时前
Swift 杀进 Android,Google 和 Apple 都要失眠了?
android·前端·swift
黄林晴3 小时前
改完代码1秒生效,Compose热重载来了!
android
黄林晴3 小时前
紧急适配!Android 联系人权限重构,READ_CONTACTS 全面废弃
android