bma*_*mat 2 android android-layout hierarchyviewer
我正在 hierarchyviewer 中分析平板电脑 UI,我注意到测量时间中存在以下模式(从树的底部开始向上移动):
... ~40 毫秒 ... ~80 毫秒 ... ~160 毫秒 ... ~320 毫秒 ... ~640 毫秒 ... ~1280 毫秒 ...
我认为问题是带有嵌套权重的 LinearLayouts,因此我删除了整个层次结构中的所有 LinearLayouts 和权重。现在我有这个:
... ~40 毫秒 ... ~80 毫秒 ... ~160 毫秒 ... ~160 毫秒 ... ~160 毫秒 ... ~310 毫秒 ...
更好,但每隔几个级别它仍然会翻倍。可能是什么原因造成的?
这是此路径的完整层次结构(请原谅长度......请随时向我提出您最好的优化技巧):
[generated layouts]
*RelativeLayout [309 ms]
FrameLayout [164 ms]
NoSaveStateFrameLayout [160 ms]
*RelativeLayout [151 ms]
*RelativeLayout [77 ms]
ListView [45 ms]
GridLayout [46 ms]
Spinner [4.4 ms]
TextView [0.1 ms]
Run Code Online (Sandbox Code Playgroud)
*观看时间加倍
任何建议将不胜感激!提前致谢。
除了嵌套权重之外,还有什么原因导致测量时间呈指数级增长?
西蒙之前的回答不太正确。确实有一个测量通道和一个布局通道,但仅此事实并不会导致指数爆炸。
如果您将跟踪放在层次结构中各个 View 的 onMeasure() 和 onLayout() 内,您会发现布局传递不是问题:每个 View 上的 onLayout() 仅被调用一次,使其成为线性时间遍历。测量过程是问题所在——对于ViewGroup 的某些子类,使用一些参数, onMeasure() 最终会调用每个子类的 onMeasure() 两次,这当然会导致您所看到的行为。
relativeLayout 是这些“坏公民”之一,它对每个孩子进行两次测量,与您的观察结果一致。
当子级具有 MATCH_PARENT 和非零权重时,另一个坏公民(如您所知)是 LinearLayout。我查看了实现,大致了解了它在做什么——首先,它递归地测量子级一次,看看它们想要多大,然后,如果有任何松弛(或收缩),它就会测量子级再次使用非零权重以分配松弛。
请注意,RelativeLayout 通常被认为是指数爆炸的解决方案,尽管它是导致指数爆炸的坏公民之一。我相信原因是RelativeLayout 具有足够的表现力,LinearLayout 的深层层次结构可以重新表示为单个RelativeLayout。这是非常重要的一点——如果您只是将 LinearLayouts 替换为RelativeLayouts 而不展平层次结构,您仍然会有指数测量时间。
我不清楚指数爆炸是否最终可以在核心库中简单地优化掉(也许通过将现有的测量传递分为聚集首选大小传递和分布松弛传递,每个传递都可以是线性时间完成并且不需要互相调用)或者 LinearLayout 和relativelayout 的契约中是否有某些东西使得递归双子测量本质上是必要的。
| 归档时间: |
|
| 查看次数: |
1162 次 |
| 最近记录: |