在Activity 的启动过程中,调用ActivityThread 的handleResumeActivity 方法时,先得到一个与Activity 关联的PhoneWindow 对象,然后通过PhoneWindow 来获取DecorView。

PhoneWindow.java

public final View getDecorView() {
  if (mDecor == null) {
    installDecor();
  }
  return mDecor;
} private void installDecor() {
  if (mDecor == null) {
    // 生成DecorView
    mDecor = generateDecor();
    mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
    mDecor.setIsRootNamespace(true);
  }
  if (mContentParent == null) {
    // 根据Window 样式确定DecorView 中的布局内容,mContentParent 就是DecorView 的第一个子View,也是我们写的Activity onCreate()中setContentView() 的父View
    mContentParent = generateLayout(mDecor);
    final DecorContentParent decorContentParent = (DecorContentParent) mDecor.findViewById(R.id.decor_content_parent);
  }
  ...
}

DecorView 是PhoneWindow 的一个内部类,继承FrameLayout,generateDecor() 也是像平时我们自定义View 是new 一个DecorView,只不过多了一个featureId 参数,该参数如果是-1,表示这个View 是一个DecorView

protected DecorView generateDecor() {
  return new DecorView(getContext(), -1);
} private final class DecorView extends FrameLayout {
  public DecorView(Context context, int featureId) {
    super(context);
    mFeatureId = featureId;
  }
}

因此,DecorView 中的布局是怎样的,主要是由generateLayout(mDecor) 决定的

protected ViewGroup generateLayout(DecorView decor) {
  // 获取Window 的样式
  TypedArray a = getWindowStyle();
  ...
  final WindowManager windowService = (WindowManager) getContext().getSysteService(Context.WINDOW_SERVICE);
  if (windowService != null) {
    final Display display = windowService.getDefaultDisplay();
    ...  
  }
  final Context context = getContext();
  final int targetSdk = context.getApplicationInfo().targetSdkVersion();
  ...
  WindowManager.LayoutParams params = getAttributes();
  // Inflate the window decor
  int layoutResource;
  int features = getLocalFeatures();
  if (){
    // 判读features 中是否包含FEATURE_SWIPE_TO_DISMISS
    
  } else if() {
    // 如果features 包含自定义的Title
    layoutResource = R.layout.screen_custom_title;
  } else {
    // 如果window 属性没有任何装饰(没有TitleBar,没有ActionBar 等)
    layoutResource = R.layout.screen_simple;
  }
  mDecor.startChanging();
  // 可以看到DecorView 也是通过inflate 加载布局的,系统framework 默认的布局资源位于frameworks\base\core\res\res\layout 目录下
  View in = mLayoutInflater.inflate(layoutResource, null);
  decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
  mContentRoot = (ViewGroup) in;
  ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
  if (contentParent == null) {  
    // 抛出异常
  }
  ...
  mDecor.finishChanging();
  return contentParent;
}

由此得出,DecorView 是根据不同的window 属性通过inflate() 方法加载位于frameworks\base\core\res\res\layout 目录下对应的布局资源生成的。至于LayoutInflate.inflate() 方法是如何加载布局文件并解析生成View 的,将在下篇文章中分析。

DecorView 的创建的更多相关文章

  1. 简析Window、Activity、DecorView以及ViewRoot之间的错综关系

    一.职能简介 Activity Activity并不负责视图控制,它只是控制生命周期和处理事件.真正控制视图的是Window.一个Activity包含了一个Window,Window才是真正代表一个窗 ...

  2. Android面试收集录11 Window+Activity+DecorView+ViewRoot之间的关系

    一.职能简介 Activity Activity并不负责视图控制,它只是控制生命周期和处理事件.真正控制视图的是Window.一个Activity包含了一个Window,Window才是真正代表一个窗 ...

  3. Android DecorView 与 Activity 绑定原理分析

    一年多以前,曾经以为自己对 View 的绘制已经有了解了,事后发现也只是懂了些皮毛而已.经过一年多的实战,Android 和 Java 基础都有了提升,时机成熟了,是时候该去总结 View 的绘制流程 ...

  4. 【android】侧滑关闭activity

    最近在使用IOS系统的时候,发现侧滑关闭很实用,因为单手就可以操作,不需要点击左上角的回退按钮.或者返回键了. 所以打算在android上实现这个技术. 需求: 1:IOS只能在屏幕边缘开始,往中间进 ...

  5. Android应用程序窗口(Activity)实现框架简要介绍和学习计划

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8170307 前面我们学习了SurfaceFli ...

  6. 理解Window和WindowManger

    一.Window简介 作用:桌面上显示一个类似悬浮的东西. 介绍:Window是一个抽象类,实现是由PhoneWindow.WindowManager是外界访问Window的入口.但是最终实现是在Wi ...

  7. Android应用运行过程(转)

    源:Android应用运行过程 首先,ActivityThread从main()函数开始执行,调用prepareMainLooper()为UI线程创建一个消息队列(MessageQueue). 然后创 ...

  8. 源码分析篇 - Android绘制流程(一)窗口启动流程分析

    Activity.View.Window之间的关系可以用以下的简要UML关系图表示,在这里贴出来,比较能够帮组后面流程分析部分的阅读. 一.Activity的启动流程 在startActivity() ...

  9. [置顶] 长谈:关于 View Measure 测量机制,让我一次把话说完

    <倚天屠龙记中>有这么一处:张三丰示范自创的太极剑演示给张无忌看,然后问他记住招式没有.张无忌说记住了一半.张三丰又慢吞吞使了一遍,问他记住多少,张无忌说只记得几招了.张三丰最后又示范了一 ...

随机推荐

  1. Oracle index unusable和invisible的差别

    摘录自11g的官方文档:      UNUSABLE Specify UNUSABLE to mark the index or index partition(s) or index subpart ...

  2. BNU 25593 Prime Time 记忆化dp

    题目链接:点击打开链接 题意: 一个游戏由3个人轮流玩 每局游戏由当中一名玩家选择一个数字作为開始 目的:获得最小的得分 对于当前玩家 O .面对 u 这个数字 则他的操作有: 1. 计分 u +1 ...

  3. 工作总结 for 另类写法 循环加时间 集合合并 也是用的 static class Enumerable (IEnumerable<T>的扩展方法) (IEnumerable<T> 的 工具类) (所有集合 数组都实现IEnumerable<T>)

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  4. jmeter获取时间_time 函数

    原始时间戳13位精确到毫秒:${__time(,)} 时间戳精确到秒10位:${__time(/1000,)} 时间日期到年月日2019-04-21:${__time(yyyy-MM-dd,)} 时间 ...

  5. 在.Net MVC结构API接口中推断http头信息实现公共的权限验证过滤器演示样例

    //control   action public class TestController : ApiController { [MyAuthFilter] public string test(s ...

  6. The method getJspApplicationContext(ServletContext) is undefined for the type JspFactory的解决方法

    An error occurred at line: [31] in the generated java file: [/data/tmisnt/work/Catalina/localhost/_/ ...

  7. navicat软件设置连接mysql数据库

    navicat软件设置连接mysql数据库 适用范围及演示使用工具 适用范围:mysql全部系列(含Linux和Windows系统下的mysql) 演示使用工具:Navicat 8.0 MySQL 演 ...

  8. Android自己定义dialog中的EditText无法弹出键盘的解决

    近期我独立开发的项目<全医会>已经在内測其中了.非常快将会上架到各大应用市场.之前开发的几个项目都由于一些原因没有上架还是比較遗憾的.所以,近期我心情格外的好. 今天在做一个新项目,专为律 ...

  9. go5--数组

    package main /* 数组Array 定义数组的格式:var <varName> [n]<type>,n>=0 数组长度也是类型的一部分,因此具有不同长度的数组 ...

  10. eclipse android开发,文本编辑xml文件,给控件添加ID后,R.java,不自动的问题。

    直接编辑xml文件给控件添加id,不自动更新.原来的id写法:@id/et_tel 然后改写成这样:@+id/et_tel  然后就好了!操`1