源码分析 | Activity-setContentView

简介: 普通的一个 Activity-setContentView(),你知道它内部做了什么吗?

引言

普通的一个 Activity-setContentView(),你知道它内部做了什么吗?

概要

源码分析

我们先来看一下Activity-setContentView方法:

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

简简单单滴方法,内部调用了 getWindows.setContentView(xxx)

等等,Windows 是什么?

Windows 表示一个窗口的概念,Android 中不管是Activity,dialog,还是 Toast 它们的视图都是附加在 Windows 上,因此可以称 windows 是View的直接管理者。而Windows也只有实现类,即PhoneWindows.

我们接着去看 PhoneWindowssetContentView()

@Override
public void setContentView(int layoutResID) {
    if (mContentParent == null) {
        installDecor(); //关注点
    } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
        mContentParent.removeAllViews();
    }
     mLayoutInflater.inflate(layoutResID, mContentParent);
}

简简单单,内部执行了一个判断,然后调用 **installDecor() ** 方法。

等等,mContenParent是什么?

mContentParent 即放置我们自己布局的容器,你可以理解为,它是我们的根布局,详情看图。

我们接着去看 installDecor() 方法:

private void installDecor() {
    ...忽略掉
    mDecor = generateDecor(-1); //关注点1
    ...忽略掉
    if (mContentParent == null) {
      //关注点2
      mContentParent = generateLayout(mDecor);
    }
    ...忽略掉一大段
}

这个方法内部很繁琐,很臭很长,我们需要关注这么多吗,不需要,所以直接先进入 generateDecor().

等等,mDecor 是什么?

mDecor 是 windows 唯一视图,也就是我们 mContentParent 的爸爸。简称 DecorView,是不是回忆起了点什么。

我们接着去看 generateDecor() 方法

protected DecorView generateDecor(int featureId) {
    ...忽略一大段
    return new DecorView(context, featureId, this, getAttributes());
}

哇,这个方法爱了爱了,直接new了一个 DecorView,其他也没啥,返回回去看 installDecor() 中的关注点2-generateLayout().


我们进入 generateLayout() 方法:

protected ViewGroup generateLayout(DecorView decor) {
   //1
   TypedArray a = getWindowStyle();
   if(xx)else if(xxx) 
   else {
       layoutResource = R.layout.screen_simple;
   }
   //2
   mDecor.onResourcesLoaded(mLayoutInflater, layoutResource);
   ..忽略掉一部分
   //3
   ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
   return contentParent;
}
  1. 显示获取当前主题,然后开始判断究竟要用那个布局
  2. 将其加载到 DecorView
  3. 通过 findViewById(内部就是DecorView.findViewById)获取 R.id.content,并返回此viewGroup。

等等,这个 R.layout.screen_simple 是甚?



哦,就一个普通的布局,没什么太奇怪的。

串一遍思路

我们接下来将上面的分析整体走一遍:

  • 当我们调用Activity的 setContentView 时,内部其实是执行了 PhoneWindows(windows的唯一实例)的 setContenView()
  • PhoneWindowssetContentView() 内部会先判断当前有没有根布局 contentParent,也即就是有没有 DecorView,如果没有,执行 installDecor() 去初始化我们的 DecorViewcontentParent
  • installDecor() 方法里面,会先判断有没有 DecorView,如果没有,先new一个出来,然后判断有没有 contentParent,没有的话,就去根据当前主题,选择一个布局,并将其当做我们的根布局添加到 DecorView 中;
  • 最后 PhoneWindows-setContentView() 方法接下来就可以将我们自己的布局 inflate 进这个根布局里了;
目录
相关文章
|
7月前
|
XML 监控 Android开发
Activity详解2
Activity详解
121 1
|
7月前
|
存储
Activity详解1
Activity详解
99 0
|
7月前
|
前端开发 Java Android开发
Activity
Activity
144 0
|
SQL 人工智能 Java
Android Activity 启动流程 二:setContentView
Android Activity 启动流程 二:setContentView
|
XML 缓存 Android开发
QMUI实战(二)—Activity 和 Fragment,我们该选择谁?
在一开始,官方只提供了 Activity 来作为 UI 界面的载体,因此我们也别无选择,只能用它。而在 Android 3.0 后,Fragment 也面世了,它一开始是用于适配平板的,以邮件列表与详情的适配为例,手机端够小,因此开始展示列表,点击进入详情,而平板够大,则可以列表显示在左侧,详情显示在右侧,点击列表只是切换详情。对于这种适配场景,列表页和详情页必须在同一个 Activity 里了,而这便是我所知道的 Fragment 诞生的场景了。
212 0
|
传感器 存储 定位技术
Activity初学乍练
Activity是一个应用程序的组件,他在屏幕上提供了一个区域,允许用户在上面做一些交互性的操作,比如打电话,照相,发送邮件,或者显示一个地图!Activity可以理解成一个绘制用户界面的窗口,而这个窗口可以填满整个屏幕,也可能比屏幕小或者浮动在其他窗口的上方!
|
Java 调度 Android开发
Activity登堂入室
Activity调用startActivity后最后会调用attach方法,然后在PolicyManager实现一个Ipolicy接口,接着实现一个Policy对象,接着调用makenewwindow(Context)方法,该方法会返回一个PhoneWindow对象,而PhoneWindow是Window的子类,在这个PhoneWindow中有一个DecorView的内部类,是所有应用窗口的根View,即View的老大,直接控制Activity是否显示(引用老司机原话..),好吧,接着里面有一个LinearLayout,里面又有两个FrameLayout他们分别拿来装ActionBar和Cus
105 0
|
XML Java Android开发
第二讲 Activity详解
第二讲 Activity详解
211 0
第二讲 Activity详解
|
Java Android开发
【Android 事件分发】事件分发源码分析 ( Activity 中各层级的事件传递 | Activity -> PhoneWindow -> DecorView -> ViewGroup )
【Android 事件分发】事件分发源码分析 ( Activity 中各层级的事件传递 | Activity -> PhoneWindow -> DecorView -> ViewGroup )
236 0
【Android 事件分发】事件分发源码分析 ( Activity 中各层级的事件传递 | Activity -> PhoneWindow -> DecorView -> ViewGroup )