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图:

更多相关文章

  1. button
  2. Android(安卓)DialogFragment底部弹出菜单
  3. Android(安卓)Studio的各种冷知识,黑科技
  4. Android(安卓)Loader详解二:使用加载器
  5. Android中service的使用
  6. view中显示部分区域
  7. adb 5037 端口占用解决
  8. Android(安卓)使用V4包的Fragment遇到的问题
  9. Android(安卓)1000实例代码集结(三 )

随机推荐

  1. 消息推送系统设计
  2. vue中判断是iOS,安卓,以及微信的方法
  3. Android(安卓)Studio与Eclipse SDK无法更
  4. Android(安卓)Studio提示“Cause: jcente
  5. Android学习--《数据的保存》
  6. Android实现聊天型笔记编辑器
  7. Android(安卓)touch 事件的处理流程
  8. 2019最新Android常用开源库总结(From:知乎)
  9. framework
  10. android中listview中设计左图标