上周在github上看到关于提高Android布局加载速度的开源库X2C。对于Android开发设置布局不外乎于两种方式:xml、Java编码。过去有段时间我也尝试着抛弃xml直接使用代码去建立布局,但问题在于代码建立的布局没法实时查看、布局过于复杂用代码实现不太容易等缺点。X2C开源库的功能大体上是经过编写xml文件产出代码文件,最终经过java代码编写UI布局。java
虽然咱们日常在Android开发中经常适用xml文件编写UI布局,那为什么不使用易用可视化的xml布局实现方式而采用代码方式实现呢。其实xml方式的UI布局多一层对xml文件的读取和解析将xml文件中的各类UI控件最终实例化成Java代码控件,因此最终仍是回到以Java代码实现布局的步骤,所以为何说Java代码实现布局会比xml加载效率更高了,其大致上咱们能够经过Android源码探一探究竟。git
这里主要拿Activity的布局加载做为例子。以前提到过布局加载方法setContentView提供两种方式提供xml文件的资源ID加载xml文件,另一种是View对象。
当前sdk版本中会根据BuildSdk版本不一样建立不一样的适配AppCompatDelegate对象,但这里要讲的建立布局仍是在AppCompatDelegateImplV9中实现并未作重写操做。UI布局加载View对象的方式这里很少加以解析,只是经过contentParent将须要呈现的UI布局经过addView方法实现。下面仍是主要看看加载xml文件具体是如何实现加载布局的。github
xml文件是由LayoutInflater加载,LayoutInflater是一个抽象类经过from获取context,而后方法inflate载入resId和contentParent。缓存
而后经过Resources对象的getLayout方法获取到XmlResourceParser。getLayout经过loadXmlResourceParser加载layout资源,其中在ResourcesImpl获得TypedValue,而后调用ResourcesImpl的loadXmlResourceParser判断是从xml缓存区cachedXmlBlocks中获得XmlResourceParser仍是从新建立XmlResourceParser结果。布局
经过AssetManager的getResourceValue调用native层级loadResourceValue方法实例化TypedValue,若在Resources中未能找到当前布局的xml缓存则经过native层级openXmlBlockAsset建立XmlBlock对象。XmlBlock调用newParser方法获取到XmlResourceParser对象。ui
获取到XmlResourceParser以后调用inflate方法。其中关键建立布局DOM代码在rInflate方法,方法内部while循环以及递归操做。除去上层逻辑判断异常处理部分代码后,重心关注最后View的建立和布局拼接组合。经过createViewFromTag建立View对象而后经过addView将实例化的布局控件装载到ViewGroup(Parent)。那建立View的过程是代码片是经过好几种方式找到正确的建立View方法而建立的,大体能够分为Factory二、Factory、privateFactory以及LayoutInflater的createView方法。就近原则先看看createView方法的代码会发现View的建立是经过反射方式获取View最终newInstance实例化。而以上Factory二、Factory、privateFactory方式也大同小异都是经过反射建立View。编码
图1-xml加载布局大体过程spa
加载xml形式的setContentView内部经过反射建立布局确实不比直接用代码建立布局来得高效。每种方式总会存在好与很差的状况,选择哪一种形式去实现最终仍是由开发者自行斟酌选择最佳方案。最后除了原生方式实现布局建立其实还存在其余更多样化的编写布局方式,例如:Mist、facebook的litho。据说litho加载布局方式可能会更好更高效,但也待进一步证明和调研。3d