【Android】ViewRootImpl、WindowManagerGlobal和WindowManager之间的关系

前面介绍了ViewRootImplChoreographer的相互配合刷新界面:界面是如何刷新的流程

ViewRootImpl的描述是这样的:

The top of a view hierarchy, implementing the needed protocol between View and the WindowManager. This is for the most part an internal implementation detail of WindowManagerGlobal

翻译一下

View层次结构的顶部,实现视图和窗口管理器之间所需的协议。这在很大程度上是一种WindowManagerGlobal详细的内部实现

View mView作为ViewRootImpl的一个属性,承担了所有和视图相关的操作。

我们可以猜测 mView就是用户看到的屏幕界面。

为了验证猜测,下面我们看一下mView是从哪里来的,是怎么添加到ViewRootImpl中的。

绑定视图到Window

从最熟悉的地方开始:

#Activity
public void setContentView(View view, ViewGroup.LayoutParams params) {
    
    
    getWindow().setContentView(view, params);
}

Window的实现类是PhoneWindow,Decor是Activity View视图最外层的ViewGroup,由PhoneWindow创建:

#PhoneWindow
@Override
public void setContentView(View view, ViewGroup.LayoutParams params) {
    
    
    installDecor();
    mContentParent.addView(view, params);
}

Window和WindowManager的创建

Activityattach创建了PhoneWindow的实例:

#Activity
final void attach() {
    
    
        mWindow = new PhoneWindow(this, window, activityConfigCallback);
        mWindow.setWindowManager(
                (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
                mToken, mComponent.flattenToString(),
                (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
}

PhoneWindow的父类Window设置WindowManager

#Window
public 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);
}

现在我们知道Activity创建了一个Window:PhoneWindow,PhoneWindow中有ViewGroup:Decor,还有WindowManager

绑定View和WindowManager

handleResumeActivity方法中,调用了WindowManageradd方法,第一个参数是decor,这个WindowManager就是上文说PhoneWindow的WindowManager:

#ActivityThread
@Override
public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
        String reason) {
    
    
        
    final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);

    final Activity a = r.activity;

    if (r.window == null && !a.mFinished && willBeVisible) {
    
    
        r.window = r.activity.getWindow();
        //Decor
        View decor = r.window.getDecorView();
        decor.setVisibility(View.INVISIBLE);
        //WindowManager
        ViewManager wm = a.getWindowManager();
        WindowManager.LayoutParams l = r.window.getAttributes();
        a.mDecor = decor;

        if (a.mVisibleFromClient) {
    
    
            if (!a.mWindowAdded) {
    
    
                a.mWindowAdded = true;
                //Add
                wm.addView(decor, l);
            } else {
    
    
                a.onWindowAttributesChanged(l);
            }
        }
    } 
}

添加view到Global

WindowManagerImplWindowManager的实现类:

#WindowManagerImpl

private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();

@Override
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
    
    
    applyDefaultToken(params);
    mGlobal.addView(view, params, mContext.getDisplayNoVerify(), mParentWindow,
            mContext.getUserId());
}

绑定WindowManagerGlobal和ViewRootImpl

WindowManagerGlobal.addView创建了ViewRootImpl,并且设置了View

#WindowManagerGlobal

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) {
    
    

            root = new ViewRootImpl(view.getContext(), display);

            view.setLayoutParams(wparams);

            mViews.add(view);
            mRoots.add(root);
            mParams.add(wparams);

            root.setView(view, wparams, panelParentView, userId);
            
        }
}

总结

  1. Activity创建PhoneWindow
  2. Activity设置PhoneWindow的View和WindowManager
  3. Activity Resume时,通过WindowManager添加View
  4. WindowManager实际调用的WindowManagerGlobal
  5. WindowManagerGlobal创建了ViewRootImpl,并且给ViewRootImpl设置View

猜你喜欢

转载自blog.csdn.net/qq_23049111/article/details/127104356
今日推荐