[android_linux] 05_源码查看_Activity、Window和View的关系

Android 4.0

源码查看_Activity、Window和View的关系

Activity的attach()方法,什么时候被调用的? ContextImpl.java
|——startActivity(Intent intent, Bundle options) {}
    |——mMainThread.getInstrumentation(). execStartActivity
    |——ActivityThread
    public Instrumentation getInstrumentation()
    {
        return mInstrumentation;
    }
       |——final ActivityMonitor am = mActivityMonitors.get(i);
          |——newActivity
             |——activity.attach()
通过ContextImpl的startActivity()方法,得到ActivityMonitor(Instrumentation的内部类 ),然后调用 newActivity方法,在里面调用activity.attach()方法
Activity.attach()方法源码
private Window mWindow;
final void attach(Context context, ActivityThread aThread,
            Instrumentation instr, IBinder token, int ident,
            Application application, Intent intent, ActivityInfo info,
            CharSequence title, Activity parent, String id,
            NonConfigurationInstances lastNonConfigurationInstances,
            Configuration config) {
        attachBaseContext(context);
 
        mFragments.attachActivity(this, mContainer, null);
 
        mWindow = PolicyManager.makeNewWindow(this);
        mWindow.setCallback(this);
        mWindow.getLayoutInflater().setPrivateFactory(this);
        if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
            mWindow.setSoftInputMode(info.softInputMode);
        }
        if (info.uiOptions != 0) {
            mWindow.setUiOptions(info.uiOptions);
        }
        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;
        mLastNonConfigurationInstances = lastNonConfigurationInstances;
 
        mWindow.setWindowManager(
                (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
                mToken, mComponent.flattenToString(),
                (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
        if (mParent != null) {
            mWindow.setContainer(mParent.getWindow());
        }
        mWindowManager = mWindow.getWindowManager();
        mCurrentConfig = config;
    }
PolicyManager  
  ① |--makeNewWindow
   public static Window makeNewWindow(Context context) {
        return sPolicy.makeNewWindow(context);
   }
   ②|--private static final IPolicy sPolicy;
   |--IPolicy 
   public interface IPolicy {
        public Window makeNewWindow(Context context);

        public LayoutInflater makeNewLayoutInflater(Context context);

        public WindowManagerPolicy makeNewWindowManager();

        public FallbackEventHandler makeNewFallbackEventHandler(Context context);
   }
   |--IPolicy必须被com.android.internal.policy.impl下的Policy类实现并调用,调用里面的makeNewWindow()方法
   ③public class Policy implements IPolicy {
       public Window makeNewWindow(Context context) {
           return new PhoneWindow(context);
       }
    }
   ④|--PhoneWindow下的getLayoutInflater()
   private LayoutInflater mLayoutInflater; 
  @Override
  public LayoutInflater getLayoutInflater() {
       return mLayoutInflater;
  }
  ⑤|-- PhoneWindow下的setContentView
   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 && !isDestroyed()) {
        cb.onContentChanged();
    }
    }
①在Activity创建时调用attach方法
attach方法中会调用PolicyManager.makeNewWindow()来创建一个Window对象,而实际工作的是IPolicy接口的makeNewWindow方法
③在IPolicy的实现类Policy中的makeNewWindow方法中创建了PhoneWindow
④通过Activity的onCreate方法中调用setContentView方法,实际是调用PhoneWindow的setContentView中向ViewGroup(root)中添加了需要显示的内容
⑤如果mContentParent为null,那么调用installDecor来初始化一个DecorView extends FrameLayout,否则就用当前mContentParent(Viewgroup)添加要显示的View。

所以Activity类中attach的方法优先于onCreate方法,因为attach方法是创建了一个PhoneWindow对象,如果不是优先于onCreate方法,那么setContentView方法设置的布局就没有Window对象依赖了。
时序图:Activity,Window和View关系时序图