Android的布局测量时间加倍每一步层次 [英] Android layout measuring time doubles with each step up the hierarchy

查看:207
本文介绍了Android的布局测量时间加倍每一步层次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在分析hierarchyviewer平板UI,我注意到在衡量以下模式倍(从树的根部开始,动起来):

I'm analyzing a tablet UI in hierarchyviewer and I noticed the following pattern in measure times (starting from the base of the tree and moving up):

...〜40毫秒...〜80毫秒...〜160毫秒......〜320毫秒......〜640毫秒...〜1280℃MS ...

... ~40 ms ... ~80 ms ... ~160 ms ... ~320 ms ... ~640 ms ... ~1280 ms ...

我认为这个问题是嵌套的权重LinearLayouts,所以我删除整个层次中的所有LinearLayouts和权重。现在我有这样的:

I assumed the problem was LinearLayouts with nested weights, so I removed ALL LinearLayouts and weights in the whole hierarchy. Now I have this:

...〜40毫秒...〜80毫秒...〜160毫秒......〜160毫秒......〜160毫秒......〜310毫秒...

... ~40 ms ... ~80 ms ... ~160 ms ... ~160 ms ... ~160 ms ... ~310 ms ...

好转,但仍每隔几级增加一倍。 什么引起的?

Better, but it still doubles every few levels. What could be causing this?

下面是此路径的完整的层次(原谅长......随时向我扔你最好的优化建议):

Here is the full hierarchy for this path (pardon the length... feel free to throw your best optimization tips at me):

[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]

*鉴于时间双打

*view time doubles

任何意见,将大大AP preciated!先谢谢了。

Any advice will be greatly appreciated! Thanks in advance.

除嵌套的权重,是什么原因造成测量时间呈指数增长?

推荐答案

previous答案是不完全正确。
真有一个措施,传球和布局传球,
但仅凭这一事实不会导致指数爆破。

Previous answer from Simon isn't quite right. True there's a measure pass and and a layout pass, but that fact alone doesn't cause exponential blowup.

如果你把里面的痕迹onMeasure()和onLayout()在层级的不同意见,
你会发现,在布局的过程还不是一个问题:onLayout()
只有从每查看调用一次,使其成为一个线性时间的遍历。
这项措施传球是problem--为的的ViewGroup的一些的子类,
用的部分的参数,onMeasure()最终调用每个孩子的onMeasure()两次,
这当然会导致正是您所看到的行为。

If you put traces inside onMeasure() and onLayout() on the various Views in the hierarchy, you'll find that the layout pass is not a problem: onLayout() only gets called once on each View, making it a linear-time traversal. The measure pass is the problem-- for some subclasses of ViewGroup, with some parameters, onMeasure() ends up calling each child's onMeasure() twice, which of course leads to exactly the behavior you're seeing.

RelativeLayout的是衡量每个孩子的两倍,这些坏公民之一,
用你的观察同意。

RelativeLayout is one of these "bad citizens" that measures each child twice, agreeing with your observation.

另一个不好的公民(如你所知)
是的LinearLayout当孩子有MATCH_PARENT和非零权重。
我看的执行情况和我大致遵循以下就是它的doing--
首先它递归衡量孩子一次,来看看他们希望有多大是,
然后,如果有任何松弛(或收缩),
它再次测量非零权重的孩子
为了分发懈怠。

Another bad citizen (as you know) is LinearLayout when children have MATCH_PARENT and nonzero weights. I've looked at the implementation and I roughly follow what it's doing-- first it recursively measures the children once to see how big they'd like to be, then, if there is any slack (or shrinkage), it measures the children with nonzero weights again in order to distribute the slack.

注意的RelativeLayout经常被作为解决
指数爆破,即使它是坏公民导致其中的一个。
我相信的理由是,RelativeLayout的是前pressive
足够LinearLayouts的深层次可以被重新前pressed作为单一RelativeLayout的。
这是一个非常重要的point--如果只需更换LinearLayouts
与没有压扁层次RelativeLayouts,你仍然有指数
测量时间。

Note that RelativeLayout is often cited as a solution to the exponential blowup, even though it is one of the bad citizens causing it. I believe the reasoning is that RelativeLayout is expressive enough that deep hierarchies of LinearLayouts can be re-expressed as a single RelativeLayout. This is a very important point-- if you simply replace LinearLayouts with RelativeLayouts without flattening the hierarchy, you'll still have exponential measure times.

这我不清楚指数爆破是否是一件
可最终在核心库进行简单的优化掉
(或许通过分离现有措施传递到一个gather- preferred,大小通
和一个分发-松弛通,其每一个可以在线性时间内完成
并且不需要打电话给对方)
或者是否有东西在的LinearLayout的
和的RelativeLayout的合同,使递归
双量测的子女固有必要的。

It's unclear to me whether the exponential blowup is something that can be eventually be simply optimized away in the core libraries (perhaps by separating the existing measure pass into a gather-preferred-sizes pass and a distribute-slack pass, each of which can be done in linear time and which don't need to call each other) or whether there is something in LinearLayout's and RelativeLayout's contracts that make the recursive double-measuring-of-children inherently necessary.

这篇关于Android的布局测量时间加倍每一步层次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆