rhythm_of_rain 发表于 2013-1-30 04:03:05

Android中Activity,View,Window之间的关系

1.首先来看Activity中的attach()方法,在调用onCreate()之前会调用attach(),在这里我们先不管是谁调用这个方法。下面来看一下代码片段(Activity.java):
 
// attach()中的一个语句,返回一个Window对象mWindow = PolicyManager.makeNewWindow(this); 
 从上面可以看到attach()方法调用PolicyManager.makeNewWindow(this),得到了一个Window对象(实际上是PhoneWindow对象,Window是一个抽象类),而PolicyManager则利用Policy中的makeNewWindow()方法返回一个PhoneWindow对象。请看下面的代码片段(PolicyManager.java):
 
// sPolicy为Policy对象,实现了接口IPolicy    public static Window makeNewWindow(Context context) {      return sPolicy.makeNewWindow(context);    } 
 再看下面的代码(Policy.java):
 
// 这里就是返回了一个PhoneWindow对象public PhoneWindow makeNewWindow(Context context) {      return new PhoneWindow(context);    }  
所以,在一个Activity构造的时候,一定会构造一个Window对象,并且只有一个。上面的一些代码就是实例化了一个Window。Window对象的作用下面会提到。


2.下面我们来看setContentView()方法,这是它的代码片段(Activity.java,有三个重载的方法):
 
/**   * Set the activity content from a layout resource.The resource will be   * inflated, adding all top-level views to the activity.   *      * @param layoutResID Resource ID to be inflated.   */    public void setContentView(int layoutResID) {      getWindow().setContentView(layoutResID);    }    /**   * Set the activity content to an explicit view.This view is placed   * directly into the activity's view hierarchy.It can itself be a complex   * view hierarhcy.   *      * @param view The desired content to display.   */    public void setContentView(View view) {      getWindow().setContentView(view);    }    /**   * Set the activity content to an explicit view.This view is placed   * directly into the activity's view hierarchy.It can itself be a complex   * view hierarhcy.   *      * @param view The desired content to display.   * @param params Layout parameters for the view.   */    public void setContentView(View view, ViewGroup.LayoutParams params) {      getWindow().setContentView(view, params);    }从上面的代码中可以知道,这三个重载的方法,都是调用了getWindow().setContentView(),而getWindow()方法就是返回一个Window对象(就是前面attach得到的一个PhoneWindow对象,引用变量是mWindow),接下来我们定位到PhoneWindow中(PhoneWindow.java):
 
// 跟Activity中的三个重载方法是意义对应的@Override    public void setContentView(int layoutResID) {      if (mContentParent == null) {            installDecor();      } else {            mContentParent.removeAllViews();      }      mLayoutInflater.inflate(layoutResID, mContentParent);      final Callback cb = getCallback();      if (cb != null) {            cb.onContentChanged();      }    }    @Override    public void setContentView(View view) {      setContentView(view, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));    }    @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();      }    } 在上面三个方法中,我们要看是两个引用变量:mContentParent,mLayoutInflater。分别是ViewGroup对象和LayoutInflater对象。这个是mContentParent就是Winodw的ViewRoot(根视图,这是逻辑性的根视图,实际就是View或ViewGroup),通过mContentParent.addView()来添加各种View,达到我们所要的效果。其实,Activity就是一个控制单元,而Window本身不是一个视图(View),Window就是一个承载模型,而View才是真正的显示视图。而LayoutInflater的作用是把资源文件(布局文件)加载成一个View(使用LayoutInflaterd的inflate(int resource, ViewGroup root)方法)。
 
3.WindowManagerService接受的消息,并且回调Activity函数,onKeyDown()....
 
4.如何动态的添加一个layout并且显示出来,请看下面的代码片段:
 
// 这里跳过了Activity的setContentView()方法getWindow().setContentView(LayoutInflater.from(this).inflate(R.layout.main, null)); 下面再传一张UML图:
http://ww1.sinaimg.cn/mw690/50b1a8edgw1dyvswtwjg0j.jpg
 
 
页: [1]
查看完整版本: Android中Activity,View,Window之间的关系