标签:
转自:http://hi.baidu.com/xiaofanqing/blog/item/8261ac114ab14f64cb80c435.html
我这里根据我个人的理解来讲讲我个人对这3个概念的理解。当然这里设计到通用的事件窗口模型等通用GUI设计,我这里就不打算讲了,纯粹从概念上来进行区分。
但在用户级别,程序员可能根愿意理解成为一个界面的载体。但仅仅是个载体,它本身并不负责任何绘制。Activity的内部实现,实际上是聚了一个 Window对象。Window是一个抽象类,它的具体是在android_src_home/framework/policies/base /phone/com/android/internal/policy/impl目录下的PhoneWindow.java。
下面是PhoneWindow中的setContentView方法的实现:
@Override
public void setContentView(View view, ViewGroup.LayoutParams params) {
if (mContentParent == null) {
installDecor();
else {
mContentParent.removeAllViews();
}
mContentParent.addView(view, params);
final Callback cb = getCallback();
if (cb != null) {
cb.onContentChanged();
}
}
Window内部首先判断mContentParent是否为空,然后调用installDecor方法(安装装饰器),我们看看这个方法如何实现的
private void installDecor() {
if (mDecor == null) {
mDecor = generateDecor();
true);
}
if (mContentParent == null) {
mContentParent = generateLayout(mDecor);
mTitleView = (TextView)findViewById(com.android.internal.R.id.title);
if (mTitleView != null) {
if ((getLocalFeatures() & (1 << FEATURE_NO_TITLE)) != 0) {
View titleContainer = findViewById(com.android.internal.R.id.title_container);
if (titleContainer != null) {
titleContainer.setVisibility(View.GONE);
else {
mTitleView.setVisibility(View.GONE);
}
if (mContentParent instanceof FrameLayout) {
null);
}
else {
mTitleView.setText(mTitle);
}
}
}
}
Activity--->Window--->DecorView
我们详细分析一下,类对象是如何被创建的。
Activity被创建后,系统会调用它的attach方法来将Activity添加到ActivityThread当中。我们找到Activity的attach方法如下:
final void attach(Context context, ActivityThread aThread,
int ident,
Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
Object lastNonConfigurationInstance,
HashMap<String,Object> lastNonConfigurationChildInstances,
Configuration config) {
attachBaseContext(context);
mWindow= PolicyManager.makeNewWindow(this);
mWindow.setCallback(this);
if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
mWindow.setSoftInputMode(info.softInputMode);
}
mUiThread = Thread.currentThread();
mMainThread = aThread;
mInstrumentation = instr;
mToken = token;
mIdent = ident;
mApplication = application;
mIntent = intent;
mComponent = intent.getComponent();
mActivityInfo = info;
mTitle = title;
mParent = parent;
mEmbeddedID = id;
mLastNonConfigurationInstance = lastNonConfigurationInstance;
mLastNonConfigurationChildInstances = lastNonConfigurationChildInstances;
mWindow.setWindowManager(null, mToken, mComponent.flattenToString());
if (mParent != null) {
mWindow.setContainer(mParent.getWindow());
}
mWindowManager = mWindow.getWindowManager();
mCurrentConfig = config;
}
我们看红色的代码部分,就是创建Window对象的代码。感兴趣的同学可以跟踪去看看具体是如何创建的。其实很简单,其内部实现调用了Policy对象的makeNewWindow方法,其方法直接new了一个PhoneWindow对象如下:
public PhoneWindow makeNewWindow(Context context) {
return new PhoneWindow(context);
}
这时我们已经可以把流程串起来,Activity创建后系统会调用其attach方法,将其添加到ActivityThread当中,在attach方法中创建了一个window对象。
我们回头看看Window实现里边的setContentView方法,我们看上面代码的红色部分setContentView-> installDecor-> generateDecor.
generateDecor直接new了一个DecorView对象:
protected DecorView generateDecor() {
return new DecorView(getContext(), -1);
}
我们可以去看看DecorView的实现,它是 PhoneWindow的一个内部类。实现很简单,它默认会包含一个灰色的标题栏,然后在标题栏下边会包含一个空白区域用来当用户调用 setContentView的时候放置用户View,并传递事件,这里不做详细分析,感兴趣同学可以自己研究研究。
当DecorView创建好之后再回到Window中的setContentView方法中来,见上面代码蓝色部分,调用
mContentParent.addView(view, params);
来将用户的View树添加到DecorView中。
现在总结一下:
Activity在onCreate之前调用attach方法,在attach方法中会创建window对象。window对象创建时并木有创建 Decor对象对象。用户在Activity中调用setContentView,然后调用window的setContentView,这时会检查 DecorView是否存在,如果不存在则创建DecorView对象,然后把用户自己的View 添加到DecorView中。
Android 中Activity,Window和View之间的关系
标签:
原文地址:http://www.cnblogs.com/wxishang1991/p/4882765.html