View绘制可以说是Android开发的必备技能,但是关于View绘制的的知识点也有些繁杂。
如果我们从头开始阅读源码,往往千头万绪,抓不住要领。
目前当我们写页面时,布局都是写在XML里的,我们可以思考下:布局从XML到显示到屏幕上,都发生了什么,可以分为哪几个部分?
我们将整个显示流程分解为以下几个部分
- 代码是怎么从
XML转换成View的? View是怎么添加到页面上的?- 在内存中
View到底是怎么绘制的? View绘制完成后是怎么显示到屏幕上的?
本文目录如下所示:

1. XML是怎么转换成View的?
我们都知道,在android中写布局一般是通过XML,然后通过setContentView方法配置到页面中
看来XML转换成View就是在这个setContentView中了
1.1 setContentView中做了什么
public void setContentView(int resId) {
ensureSubDecor();
ViewGroup contentParent = mSubDecor.findViewById(android.R.id.content);
contentParent.removeAllViews();
LayoutInflater.from(mContext).inflate(resId, contentParent);
mAppCompatWindowCallback.getWrapped().onContentChanged();
}
可以看到resId传给了我们熟悉的LayoutInflater,看来xml转化成View就是在LayoutInflater方法中实现的了
1.2 LayoutInflater中做了什么?
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot) {
final Resources res = getContext().getResources();
//预编译直接返回view,目前还未启用
View view = tryInflatePrecompiled(resource, res, root, attachToRoot);
if (view != null) {
return view;
}
XmlResourceParser parser = res.getLayout(resource);
try {
//真正将`XML`转化为`View`
return inflate(parser, root, attachToRoot);
} finally {
parser.close();
}
}
代码也比较简单,我们一起来分析下
- 首先我们需要明确,将
XML转化为View牵涉到一些耗时操作,比如XML解析是一个io操作,将XML转化为View涉及到反射,这也是耗时的 - 我们可以看到在解析前有个
tryInflatePrecompiled方法,这个方法就是希望可以在编译阶段直接预编译XML,在运行时直接返回构建好的View,看起来Google希望通过这种方式解决XML的性能问题。不过这个功能目前还没有启用,因此此方法直接返回null,目前生效的还是下面的方法 - 真正将
XML解析为View的还是在inflate方法中,将标签名转化为View的名称,XML中的各种属性转化为AttributeSet对象,然后通过反射生成View对象
由于篇幅原因,这里就不再粘贴inflate方法的源码了,里面主要需要注意下setFactory与setFactory2方法
在真正进行反射前,会先调用这两个方法尝试创建一下View,而且系统开放了API,我们可以自定义解析XML方式
这就给了我们一些面向切面编程的空间,可以利用这两个API实现换肤,替换字体,替换 View,提升View构建速度等操作。
1.3 小结
XML转化为View转化为主要是通过LayoutInflator来完成的,将标签名转化为View的名称,XML中的各种属性转化为AttributeSet对象,然后通过反射生成View对象
这个过程中存在一些耗时操作,比如解析XML的IO操作,通过反射生成View等,我们可以通过多种方式优化这个过程,比如将反向的耗时转移到编译期。

本文详细解析了Android中XML布局如何转换为View并显示在屏幕上,涵盖了从XML解析、View添加、绘制到显示的全过程。通过分析关键步骤,如LayoutInflater的工作、ViewGroup的添加、测量与绘制,揭示了Android UI机制的内部运作。
最低0.47元/天 解锁文章
264

被折叠的 条评论
为什么被折叠?



