一些常用的android布局,如RelativeLayout和LinearLayout(当权重非零时)有onMeasure()实现,它们测量它们的孩子两次,嵌套时导致指数运行时间。这很容易通过从叶视图的 onMeasure() 发出日志条目来验证......它被称为 2深度 时间。
有人可以就为什么会这样给出一个清晰而具体的描述吗?最重要的是,这种指数行为是由于整个合约的重要组成部分,还是只是一个可能被优化掉的实现细节?如果认为这是不可避免的,请举一个需要它的例子。
这样的例子将极大地帮助我和其他抱怨“保持布局浅”的人是繁重的,并且想知道这是否仅仅是由核心库中尚未优化的算法驱动的,或者是否真的存在阻止修复的根本困难。
也许一个最小的例子包括一个在另一个 LinearLayout 中的 LinearLayout 中的 Button(到处都有 match_parent 和 weight=1,以触发完整的指数行为),以及一些额外的参数或环境清楚地表明所有四个对 Button 的调用。 onMeasure() 确实是有意义和必要的。
我的第一个猜测是,实际上只需要两次线性时间遍历——第一次遍历收集每个人的首选尺寸,第二次遍历分配松弛和/或收缩。世界上的其他布局引擎,例如 Tex 和 Swing 以及 HTML 的布局引擎,似乎能够常规处理具有大量对齐约束和拉伸的非常深的层次结构,而不会出现任何指数爆炸,我想这就是它们的工作方式。
请注意,我不想要解释指数爆炸是如何发生的答案—— 我理解这一点,并且已经有几个帖子被问及并回答了:
- 为什么嵌套权重对性能不利?备择方案?
- Android 布局测量时间随着层次结构的每一步增加一倍
- 布局权重警告嵌套权重性能不佳
- Android Layout 层次结构的效率
- http://android-developers.blogspot.com/2009/02/android-layout-tricks-1.html
我的问题是递归双重测量是否从根本上是必要的/合理的,如果是这样,我想要一个清楚的解释/示例来说明原因。
编辑 2013/8/22:我想也许我的问题还没有解决。我将尝试澄清和解释我的动机,这次更大胆。
布局不是一个指数级的难题,世界上高效的布局引擎证明了这一点,例如 Tex 和 Swing 以及 HTML。
那么,LinearLayout 发生了什么,android 开发者社区应该如何应对呢?我不是本着责备的精神要求,而是要理解并决定如何最好地前进。
我能想到4种可能性:
- 修复核心库中的性能错误,无需更改任何合约
- 根据需要更改合约,并修复核心库中的性能错误
- 编写一个 LinearLayout 的替代方案,它具有其基本功能(即在指定比例的子项之间分配额外空间)但没有性能错误,并将其用于新应用程序
- 继续对我们的布局进行微观管理,以解决我们其余的 android 开发生涯中的性能错误。
(4) 对我个人来说不是一个严肃的选择。此外,我似乎很清楚,此时改变 LinearLayout 的行为是不切实际的,所以我也不认为 (2) 是一个严肃的选择。
剩下(1)和(3)。我有能力并且愿意亲自做任何一个,但是哪一个呢?显然,如果可能的话,(1)是更可取的——那么,有可能吗?这似乎是需要回答的关键阻碍问题,以确定如何前进。
我在核心代码和文档上花了一些时间,但还不清楚,所以这就是我在这里问这个问题的原因。