LayoutInflater源码解析

最新在阅读《Android源码设计模式解析与实战》一书,我觉得写的很清晰,每一个知识点都有示例,通过示例更加容易理解。书中的知识点有些都接触过,有的没有接触过,总之,通过阅读这本书来梳理一下知识点,可能有些东西在项目中一直在使用,然并不能笼统,清理的说明理解它。本文主要是记录阅读这本书的知识点和自己的一些理解。一来整理知识点,二来方便以后查看,快速定位。

LayoutInflater在开发中扮演者非常重要的角色,会经常使用到,通过简单的API调用即可实现,使用非常的简单,那么它内部具体是怎么实现的呢?LayoutInflater本身是一个抽象类,我们需要把它“找出来”。

public abstract class LayoutInflater {
    //代码省略
}

他是一个系统级别的服务,在加载ContextImpl时会通过如下的代码将LayoutInflater的ServiceFetcher注入到容器中:

registerService(LAYOUT_INFLATER_SERVICE, new ServiceFetcher() {
                public Object createService(ContextImpl ctx) {
                    return PolicyManager.makeNewLayoutInflater(ctx.getOuterContext());
                }});

这里调用了PolicyManager.makeNewLayoutInflater(ctx.getOuterContext()),继续往下看:


PolicyManager.java

PolicyManager中通过反射构建了Policy的实现类对象,这个类实现了IPolicy接口,通过这种方式将具体的Policy类对外隐藏实现。PolicyManager实际上是一个代理类,具体的实现是通过sPolicy对象实现的,也就是 "com.android.internal.policy.impl.Policy"。

Policy.java

通过上述代码我们看到LayoutInflater的具体实现类是PhoneLayoutInflater,我们继续查看PhoneLayoutInflater的源码:


PhoneLayoutInflater.java

代码不多,核心的代码就是重写了LayoutInflater的onCreateView方法,该方法就是在传进来的View前面加上前缀构成完整的路径。最后,根据完整的路径来构建对应的View。

具体是一个怎么样流程呢?以Activity的setContentView为例来说明:


Activity.java

Activity的setContentView实际上调用的是Window的setContentView,Window是一个抽象类,它的具体实现类是PhoneWindow,那我们继续看一下它的这个方法:

PhoneWindow.java

在分析之前我们先看一下Window的View层级图:

Window的View层级图

从上图我们看出DecorView会预先加载系统定义好的布局,这个布局又包裹了mContentParent,而这个mContentParent又包含我们自己定义的布局。在PhoneWindow的setContentView方法中也验证这一点,首先构建mContentParent对象,然后通过LayoutInflater的inflate方法将指定的布局添加到mContentParent中,那接下来我们就看看inflate方法:

LayoutInflater.java

上述的inflate方法主要有一下几步:

  • 1.解析布局xml的根标签。
  • 2.如果根标签是merge,那么就调用rInflate进行解析,rInflate会将merge下的所有子View直接添加到根标签中。
  • 3.如果是根标签是普通标签,就调用createViewFromTag进行解析。
  • 4.调用rInflate就系temp根元素下的所有子View,并将这些View添加到temp中。
  • 5.返回解析到的根视图。

我们先看一下解析单个元素的方法createViewFromTag:

LayoutInflater.java

createViewFromTag会将该元素的parent和名字传递过来,当这个tag的名字中没有包含“.”时,LayoutInflater会认为这是Android自带的View,例如我们在xml声明一个内置View大概是这样的:

<TextView
     android:id="@+id/tv_title"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content" />

这里的TextView就是xml元素的名字,因为就会调用onCreateView来解析这个TextView标签。当我们使用自定义View时,必须写完整的路径,如下所示:

<com.gfd.view.MyView
     android:id="@+id/share_view"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content" />

此时就会调用createView来解析,为什么要这样处理呢?它们又有什么不同呢?

在上面提到的PhoneLayoutInflater中,它重写了onCreateView方法,该方法就是在View的前面添加了“android.widget”,然后再传递给createView去解析。也就是说内置View和自定义的View最终都调用了createView就行解析,只是Google为了开发者在XML中更方便使用内置的View,只写名字而不写完整的路径。那我们就看一下该方法的具体实现:

LayoutInflater.java

createVeiw的代码相对比较简单,如果有前缀就构造View的完整路径,并将该类加载到虚拟机中,然后获取该类的构造方法并加入缓存中,然后在通过构造方法创建该View的对象,最后将该View对象返回。这个是解析单个View,我们的窗口是一颗视图树,LayoutInflater需要解析这颗树,这个功能就交给了rInflate方法,具体的方法实现如下:


LayoutInflater.java

rInflate通过深度优先遍历来构造视图树,每解析到一个View元素就会递归调用rInflate,直到这条路径的最后一个元素,然后再回溯过来将每个View添加到它们的parent。通过rInflate解析之后,整颗视图树就构建完毕。当调用了Activity的onResume之后,我们通过setContentView设置的内容就会出现在我们的视野中。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容