1.Android 视图及View绘制分析笔记之setContentView
setContentView
首先我们直接在Android Studio中找到一个Activity(请注意,本文分析的是Activity,如果你看的是AppCompatActivity,实际代码会有出入),然后找到setContent方法然后点进去,我们可以看到
public void setContentView(@LayoutRes int layoutResID) {
|
然后查找getWindow()方法
private Window mWindow; |
得知调用的是Window类的setContent()方法。然后再全类搜索mWindow,在attach方法中找到了赋值语句。
final void attach(Context context, ActivityThread aThread, |
然后就引出了我们今天主要分析的对象PhoneWindow。
PhoneWindow
查找PhoneWindow的setContentView方法,可以看到有三个重载方法。
@Override |
三个方法大体的处理流程是:
- 初始化DecorView
- 检查并处理转场动画
- 将实际要显示的Layout或者View添加到mContentParent中
- 通知Callback(即Activity)调用onContentChanged方法
DecorView
在上面的流程里面,相对比较重要的就是第一步的初始化DecorView,也就是installDecor()方法,下面我们继续分析这个方法。
private void installDecor() {
|
在installDecor()方法里,主要做的就是两件事,一个是generateDecor,生成mDecor,还有一个是generateLayout,生成mContentParent。generateDecor中,没有太多复杂逻辑,就是做一些判断,然后实例化出来一个DecorView,这里需要说一点的就是在Android7.0以前,DecorView是PhoneWindow的内部类,7.0以后,DecorView单独提出来变成了一个类,所以如果有用到反射的话,这里可能会出现问题,需要做好版本判断。然后我们看下generateLayout的逻辑:
protected ViewGroup generateLayout(DecorView decor) {
|
在generateLayout中,大概的流程是这样的。
- 先获取样式
- 设置样式到Window的features里
- 拿到features,判断对应的resourceId
- 通过resourceId,inflate出来一个ViewGroup,添加到mDecor中
- 再通过findViewById,找到刚刚inflate的ViewGroup中的 com.android.internal.R.id.content,作为mContentParent
- 在经过一系列设置
- 返回contentParent
小结
到此,我们的setContentView就已经基本走完了,剩下的就等着Activity、WindowManager、WindowManagerGlobal、ViewRootImpl去调用了,这些类的调用,涉及到了Activity的启动流程,我们会在其他笔记中详细分析这一过程。
下面会上一张整个setContentView的时序图,用来巩固一下刚才的流程。
上图为Android setContentView的时序图
系列文章
Android 视图及View绘制分析笔记之setContentView
View绘制分析笔记之onMeasure
View绘制分析笔记之onLayout
View绘制分析笔记之onDraw
1.Android 视图及View绘制分析笔记之setContentView的更多相关文章
- 3.View绘制分析笔记之onLayout
上一篇文章我们了解了View的onMeasure,那么今天我们继续来学习Android View绘制三部曲的第二步,onLayout,布局. ViewRootImpl#performLayout pr ...
- 4.View绘制分析笔记之onDraw
上一篇文章我们了解了View的onLayout,那么今天我们来学习Android View绘制三部曲的最后一步,onDraw,绘制. ViewRootImpl#performDraw private ...
- 2.View绘制分析笔记之onMeasure
今天主要学习记录一下Android View绘制三部曲的第一步,onMeasure,测量. 起源 在Activity中,所有的View都是DecorView的子View,然后DecorView又是被V ...
- Android之View绘制流程开胃菜---setContentView(...)详细分析
版权声明:本文出自汪磊的博客,转载请务必注明出处. 1 为什么要分析setContentView方法 作为安卓开发者相信大部分都有意或者无意看过如下图示:PhoneWindow,DecorView这些 ...
- Android面试,View绘制流程以及invalidate()等相关方法分析
整个View树的绘图流程是在ViewRoot.java类的performTraversals()函数展开的,该函数做的执行过程可简单概况为 根据之前设置的状态,判断是否需要重新计算视图大小(measu ...
- Android视图组成View
视图组成View 创建时间: 2013-9-13 10:51 更新时间: 2013-9-13 11:04
- Android视图控件架构分析之View、ViewGroup
在Android中,视图控件大致被分为两类,即ViewGroup和View,ViewGroup控件作为父控件,包含并管理着子View,通过ViewGroup和View便形成了控件树,各个ViewGou ...
- android事件分发源码分析—笔记
昨天晚上从源码角度复习了一下android的事件分发机制,今天将笔记整理下放在网上.其实说复习,也是按着<android开发艺术探索>这本书作者的思路做的笔记. 目录 事件是如何从Acti ...
- Android GUI之View绘制流程
在上篇文章中,我们通过跟踪源码,我们了解了Activity.Window.DecorView以及View之间的关系(查看文章:http://www.cnblogs.com/jerehedu/p/460 ...
随机推荐
- Centos6.5下docker 环境搭建
一.运行docker Linux内核版本需要在3.8以上,针对centos6.5 内核为2.6的系统需要先升级内核.不然会特别卡,退出容器. 在yum的ELRepo源中,有mainline(3.13. ...
- Java集合之HashSet
1.HashSet概述: HashSet实现Set接口,由哈希表(实际上是一个HashMap实例)支持.它不保证set 的迭代顺序:特别是它不保证该顺序恒久不变.此类允许使用null元素.HashSe ...
- 关于LESS
LESS 是动态的样式表语言,通过简洁明了的语法定义,使编写 CSS 的工作变得非常简单. 翻译成大白话:写CSS算是体力活,并没有编程的感觉,不给前端人员装逼的机会,于是就搞了这玩意,相当于编程写C ...
- [译]How to Write a Git Commit Message
原文: http://chris.beams.io/posts/git-commit/ 介绍:为什么好的commit message很重要 你浏览项目commit message的时候或多或少会有些困 ...
- FSM(状态机)、HFSM(分层状态机)、BT(行为树)的区别
游戏人工智能AI中最常听见的就是这三个词拉: FSM 这个不用说拉,百度一大堆解释, 简单将就是将游戏AI行为分为一个一个的状态,状态与状态之间的过渡通过事件的触发来形成. 比如士兵的行为有“巡逻”, ...
- 通过openswan基于Azure平台搭建VPN server
用过Azure的读者都知道,Vnet一直是Azure比较自豪的地方,尤其是VPN,Azure提供了两种VPN以及专线来保证客户数据的安全性,S2S vpn(站点到站点的,基于IPsec的),P2S v ...
- Thrift的TBinaryProtocol二进制协议分析
先上张图,说明一下thrift的二进制协议是什么东东. 报文格式编码: bool类型: 一个字节的类型,两个字节的字段编号,一个字节的值(true:1,false:0). Byte类型: 一个字节的类 ...
- C和指针 第十五章 错误报告perror和exit
15.1 错误报告 perror 任何一种程序都存在出错的可能,包括系统的函数库,当出现错误时,系统提示发生错误,标准库函数在一个外部整型变量中保存错误代码,然后把错误代码传给用户程序,提示错误原因. ...
- ffmpeg为视频添加时间戳 - 手动编译ffmpeg
FFMPEG给视频加时间戳水印 项目中需要给视频添加时间戳,理所当然最好用的办法是ffmpeg.在找到正确的做法前,还被网上的答案timecode给水了一下(水的不轻,在这里转了2天),大概是这样写的 ...
- break与continue的区别
break 在while.for.do...while.while循环中使用break语句退出当前循环,直接执行后面的代码. continue 的作用是仅仅跳过本次循环,而整个循环体继 ...