Android Window的创建过程

Activity的Window创建过程
在ActivityThread的performLaunchActivity方法中创建了Activity,并调用了Activity的attach方法
Activity
attach

在attach方法中,创建了Window的对象,并设置了Window的回调。由此可以看出,Activity中持有的mWIndow对象即为PhoneWindow。

创建PhoneWindow

 mWindow = new PhoneWindow(this, window, activityConfigCallback);
        mWindow.setWindowControllerCallback(this);
        mWindow.setCallback(this);
        mWindow.setOnWindowDismissedCallback(this);
        mWindow.getLayoutInflater().setPrivateFactory(this);

从这段代码中可以看出WIndow已经创建完成了。下面接着看Activity的视图是怎么显示在Window上的。
由于Activity的界面显示是由setContentView发起的,所以从setContentView着手分析。
setContentView

 public void setContentView(@LayoutRes int layoutResID) {
        getWindow().setContentView(layoutResID);
        initWindowDecorActionBar();
    }

由上面的这段代码可以得出,Activity的setContentView方法调用了PhoneWindow的setContentView方法。
PhoneWindow
setContentView

1 创建DecorView对象
在setContentView方法中,首先通过installDecor方法创建DecorView

mDecor = generateDecor(-1);

简单介绍一下DecorView,DecorView是一个FrameLayout。是Activity中的顶级的View。此布局会包含一个标题栏和一个内容栏。但是根据设置主题的不同,有可能标题栏会没有。但是内容栏是肯定有的。内容栏对应的id为content。所以当在activity中调用方法R.layout.activity_main。其值就是赋给DecorView中id为content的内容栏。

2 加载具体布局文件到DecorView
在generateDecor方法中,通过下面这行代码,将布局资源赋给DecorView

 mDecor.onResourcesLoaded(mLayoutInflater, layoutResource);

在DecorView中的onResourcesLoaded方法可以看出,直接将布局资源赋值给了mContentRoot。

 final View root = inflater.inflate(layoutResource, null);
 mContentRoot = (ViewGroup) root;

到此为止,Activity的布局文件已经添加到了DecorView中。

经过上述步骤,可以得出,此时虽然Window对象已经创建,DecorView也已经创建,但是DecorView还并没有添加到Window中。
ActivityThread
handleResumeActivity
在handleResumeActivity方法中首先会调用onResume方法,过程如图
这里写图片描述

然后会调用Activity的makeVisible方法

                if (r.activity.mVisibleFromClient) {
                    r.activity.makeVisible();
                }

Activity
makeVisible

void makeVisible() {
        if (!mWindowAdded) {
            ViewManager wm = getWindowManager();
            wm.addView(mDecor, getWindow().getAttributes());
            mWindowAdded = true;
        }
        mDecor.setVisibility(View.VISIBLE);
    }

从这段代码中可以看出,首先获取WindowManager对象,然后通过此WindowManager将DecorView添加到Window中。至此Activity中的Window的创建过程已经分析完了。

Dialog的Window创建过程
Dialog的Window创建过程和Activity类似。有如下几个步骤
1 创建window
在Dialog的构造方法中,创建了Window对象,并设置回调

 final Window w = new PhoneWindow(mContext);
        mWindow = w;
        w.setCallback(this);
        w.setOnWindowDismissedCallback(this);
        w.setOnWindowSwipeDismissedCallback(() -> {
            if (mCancelable) {
                cancel();
            }
        });

2 初始化DecorView并将Dialog的视图添加到DecorView中
在show方法中,给DecorView赋值

mDecor = mWindow.getDecorView();

将布局id添加到DecorView中

  public void setContentView(@LayoutRes int layoutResID) {
        mWindow.setContentView(layoutResID);
    }

3 将DecorView添加到WIndow中

 mWindowManager.addView(mDecor, l);
        mShowing = true;

对比之前的Activity的window创建过程,可以发现过程是类似的。

你可能感兴趣的:(源码)