Android Window的创建过程


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

Activity的Window创建过程

1 Activity

1.1 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着手分析。

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

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

2 PhoneWindow

2.1 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中。

3 ActivityThread

3.1 handleResumeActivity

在handleResumeActivity方法中首先会调用onResume方法,过程如图
这里写图片描述

然后会调用Activity的makeVisible方法

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

4 Activity

4.1 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

初始化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创建过程,可以发现过程是类似的。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值