你们都知道Android中加载view是从Activity的onCreate方法调用setContentView开始的,那么View的具体加载过程又是怎么的呢?这一节咱们作一下分析。java
首先追踪一下代码:android
Activity中:git
public void setContentView(int layoutResID) { getWindow().setContentView(layoutResID); } public Window getWindow() { return mWindow; } final void attach { mWindow = PolicyManager.makeNewWindow(this); }
Activity在调用onCreate()以前会调用attach()初始化mWindow,这篇文章中,咱们先无论attach()是谁调用的,也无论他是怎么被调用的。只分析一下view的加载过程。下面是PolicyManager方法:github
PolicyManager:
ide
// sPolicy为Policy对象,实现了接口IPolicy public static Window makeNewWindow(Context context) { return sPolicy.makeNewWindow(context); }
再看Policy类中的代码 布局
// 这里就是返回了一个PhoneWindow对象 public PhoneWindow makeNewWindow(Context context) { return new PhoneWindow(context); }
从而可知 Activity中的setContentView 最终调用的是PhoneWindow类中的 setContentView. this
@Override public void setContentView(int layoutResID) { if (mContentParent == null) { installDecor(); } else { mContentParent.removeAllViews(); } mLayoutInflater.inflate(layoutResID, mContentParent); final Callback cb = getCallback(); if (cb != null && !isDestroyed()) { cb.onContentChanged(); } }
installDecor()初始化了DecorView、mContentParent还有title(3.0之后的ActionBar)。DecorView是继承自FrameLayout的PhoneWindow的内部类。
spa
installDecor()中的代码:
.net
if (mContentParent == null) { mContentParent = generateLayout(mDecor);
protected ViewGroup generateLayout(DecorView decor) { View in = mLayoutInflater.inflate(layoutResource, null); decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)); }
从上面的代码看出,加载的视图添加到了DecorView上,这样Activitty加载视图的过程就完成了。试图加载过程当中出现了Activity、Window、View。Activity是Android应用程序的载体,容许用户在其上建立一个用户界面,并提供用户处理事件的API,如onKeyEvent, onTouchEvent等, 并维护应用程序的生命周期。每个Activity组件都有一个关联的Window对象,用来描述一个应用程序窗口。每个应用程序窗口内部又包含有一个View(DecorView)对象,用来描述应用程序窗口的视图。应用程序窗口视图是真正用来实现UI内容和布局的,也就是说,每个Activity组件的UI内容和布局都是经过与其所关联的一个Window对象的内部的一个View对象来实现的。code