Activity的构成

前言

最近打算把 Android 中和 View 相关的知识做一下更新,本来另一篇博客已经写的差不多了,但是发现缺少了这一块关于 Activity 的构成知识的话,在讲述事件分发机制的时候不太好开展,所以这个知识点也就相当于给后面的 View 相关知识做一个补充!废话不多说,我们现在开始。

先下结论

在解析源码之前,我们先把最终的结论得出来,方便我们后面对源码部分进行分析,在我们的 Android 设备上,我们的 Activity 构成应当是这样子的:

如果你之前从未了解过这部分知识,初看可能会觉得相当的陌生。别急,接下来我将为你从外到内介绍这幅图的含义。

  • 首先是最外层的 Activity,每次系统为我们默认建好的 MainActivity ,是继承自 AppCompatActivity 的,其实 AppCompatActivity 也是间接继承自 Activity 的一个类,所以我们的最外框层,就是 Activity
  • 接下来是 PhoneWindow,我们在 MainActivity 使用的 setContentView 加载布局方法实际上调用的是 PhoneWindow 里面的 setContentView 方法。
  • 然后就到了 DecorView 了,在 PhoneWindow 中我们会生成一个 DecorView,而且 DecorView 是继承自 FrameLayout 的一个类。
  • 最后就是 DecorView 里面的 TitleViewContentView 了,其中 TitleView 是用于显示标题的,而 ContentView 是我们平时打交道最多的地方,我们写的布局(例如 activity_main.xml)实际上都是放置在这里的,所以这也是我们加载布局的方法要叫做 setContentView 而不是直接叫做 setView 的一个原因。

好了,讲完了我们 Activity 的构成,我们现在就开始从源码的角度来看看源码是如何构成上面这幅图的吧!

源码解析

首先,我们的布局文件加载都是通过 ActivitysetContentView 方法加载进来的,也就是说一切的活动从这里开始,那么我们就来看看这个方法里面是什么吧。

public void setContentView(@LayoutRes int layoutResID) {
   
        getWindow().setContentView(layoutResID);
        initWindowDecorActionBar();
}

这里可以看到,代码里面通过 getWindow 调用了 setContentView 方法,getWindow 方法明显是会返回一个对象的,我们就来看看 getWindow 方法的源码是什么。

public Window getWindow() {
   
        return mWindow;
}

这个方法非常的简单,只是简单地返回了一个 mWindow 的变量,这个 mWindow 从前面的定义我们可以得知这是一个 Window 类型的对象,那么它又是从哪里来的呢?

我们接下来把目光聚集到 Activityattach 方法上来,它的源码如下所示:

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, String referrer, IVoiceInteractor voiceInteractor,
            Window window, ActivityConfigCallback activityConfigCallback) {
   
        attachBaseContext(context);

        mFragments.attachHost(null /*parent*/);

        mWindow = new PhoneWindow(this, window, activityConfigCallback);  // 1
        mWindow.setWindowControllerCallback(this);
        mWindow.setCallback(this);
        mWindow.setOnWindowDismissedCallback(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;
        mReferrer = referrer;
        mComponent = intent.getComponent();
        mActivityInfo = info;
        mTitle = title;
        mParent = parent;
        mEmbeddedID = id;
        mLastNonConfigurationInstances = lastNonConfigurationInstances;
        if (voiceInteractor != null) {
   
            if (lastNonConfigurationInstances != null) {
   
                mVoiceInteractor = lastNonConfigurationInstances.voiceInteractor;
            } else {
   
                mVoiceInteractor = new VoiceInteractor(voiceInteractor, this, this,
                        Looper.myLooper());
            }
        }

        mWindow.setWindowManager(
                (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
                mToken, mComponent.flattenToString(),
                (info.flags 
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值