深入理解WMS(二):Dialog与Toast源码解析(1)

getWindow().setContentView(layoutResID);

initWindowDecorActionBar();

}

从Activity的setContentView方法我们可以清楚的看到,getWindow()返回的实际上是上面创建的PhoneWindow,也就是它会调用PhoneWindow的setContentView,在该方法中会创建DecorView并完成布局视图的填充。下面我们看下PhoneWindow的setContentView的源码。

@Override

public void setContentView(View view, ViewGroup.LayoutParams params) {

// Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window

// decor, when theme attributes and the like are crystalized. Do not check the feature

// before this happens.

if (mContentParent == null) {

installDecor();

} else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {

mContentParent.removeAllViews();

}

if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {

view.setLayoutParams(params);

final Scene newScene = new Scene(mContentParent, view);

transitionTo(newScene);

} else {

mContentParent.addView(view, params);

}

mContentParent.requestApplyInsets();

final Callback cb = getCallback();

if (cb != null && !isDestroyed()) {

cb.onContentChanged();

}

mContentParentExplicitlySet = true;

}

通过上面的源码我们能清楚的看到大概分为以几个步骤:

  1. 如果没有DecorView,则需要创建,否则移除其中的mContentParent中所有的View。

  2. 将View添加到DecorView的mContentParent中。

  3. 回调Activity的onContentChanged方法通知Activity视图已经发生改变。

经过上面几个步骤,DecorView就创建完并初始化成功了。Activity的布局文件也已经成功添加到了DecorView的mContentParent中,但是这个时候DecorView还没有被WindowManager正式添加到Window中。这里需要正确理解Window的概念,Window更多表示的是一种抽象的功能集合,虽然说早在Activity的attach方法中Window就已经被创建了,但是这个时候由于DecorView并没有被WindowManager识别,所以这个时候的Window无法提供具体功能,因为它还无法接收外界的输入信息。在ActivityThread的handleResumeActivity方法中,首先会调用Activity的onResume方法,接着会调用Activity的makeVisible(),正是在makeVisible方法中,DecorView真正地完成了添加和显示这两个过程,到这里Activity的视图才能被用户看到。

void makeVisible() {

if (!mWindowAdded) {

ViewManager wm = getWindowManager();

wm.addView(mDecor, getWindow().getAttributes());

mWindowAdded = true;

}

mDecor.setVisibility(View.VISIBLE);

}

2. Dialog中的Window的创建过程

Dialog的Window的创建过程跟Activity的很相似,大体有以下几个步骤。

-1. 创建Window

Dialog的Window的创建同样是PhoneWindow,这个剩下的跟Activity还是很类似的。具体看下下面的源码。

Dialog(@NonNull Context context, @StyleRes int themeResId, boolean createContextThemeWrapper) {

if (createContextThemeWrapper) {

if (themeResId == ResourceId.ID_NULL) {

final TypedValue outValue = new TypedValue();

context.getTheme().resolveAttribute(R.attr.dialogTheme, outValue, true);

themeResId = outValue.resourceId;

}

mContext = new ContextThemeWrapper(context, themeResId);

} els

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值