DecorView添加进window的流程分析

我们知道一个DecorView的创建是在Activity中调用setContentView后,一步一步实现的。那么,创建好了DecorView后,我们是怎么将它加入进window呢?

handleLaunchActivity中的performLaunActivity方法

调用startActivity方法时,最终会调用ActivityThread的handleLaunchActivity方法创建Activity。在该方法中会调用performLaunchActivity方法,创建一个Activity。

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
         ......
        Activity a = performLaunchActivity(r, customIntent); 
        .......
    }

在performLaunchActivity方法中,会调用attach方法实例化一个PhoneWindow。

final void attach(Context context, ActivityThread aThread,
            Instrumentation instr, IBinder token, int ident,
    
        mWindow = new PhoneWindow(this);
        mWindow.setCallback(this);

attach方法之后会调用callActivityOnCreate方法,进而调用Activity的onCreate方法。

handleLaunchActivity中的handleResumeActivity方法

在该方法中首先会调用performResumeActivity方法,进而调用Activity的onResume方法。接着会调用getDecorView方法得到DecorView,然后调用getWindowManager方法得到一个WindowManager(继承了接口ViewManager的接口),最后调用该接口的addView方法将DecorView添加进去。

handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed);
            if (!r.activity.mFinished && r.startsNotResumed) {            
                try {
                    r.activity.mCalled = false;
                    mInstrumentation.callActivityOnPause(r.activity);
}
if (r.window == null && !a.mFinished && willBeVisible) {
                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;
                l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
                l.softInputMode |= forwardBit;
                if (a.mVisibleFromClient) {
                    a.mWindowAdded = true;   
                    wm.addView(decor, l);
                }

WindowManagerImpl方法

wm.addView方法调用后,实际上是进入了WindowManageImpl实现类。在该类中实例化一个WindowManagerGlobal,调用addView方法,将DecorView添加进去。

  public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
         ........
        applyDefaultToken(params);
        mGlobal.addView(view, params, mDisplay, mParentWindow);
        .........
    }
 public void addView(View view, ViewGroup.LayoutParams params,Display display, Window parentWindow) {
		......
        ViewRootImpl root;
        View panelParentView = null;  
   		......
  
           root = new ViewRootImpl(view.getContext(), display);

            view.setLayoutParams(wparams);
        
            mViews.add(view);
            mRoots.add(root);
            mParams.add(wparams);
        }
        // do this last because it fires off messages to start doing things
        try {
       
            root.setView(view, wparams, panelParentView);
        } catch (RuntimeException e) {
          }

在该方法中首先会实例化一个ViewRootImpl,在调用ViewRootImpl的setView方法将DecorView加载到Window中,在setView方法中会调用window的addToDisplay方法,将DecorView显示出来,decorview会将WindowManagerImpl设置为顶层ViewGroup。然后进行绘制过程,将View绘制出来。

ViewRootImpl的performTraversals方法

在该方法中依次调用performMeasure,performLayout和performDraw方法,其内部分别调用measure,layout,draw方法,完成View的绘制。

猜你喜欢

转载自blog.csdn.net/qq_38256015/article/details/84196751