0

我有一个相当复杂的 UI - 很多视图和相当多的层次结构。我正在努力减少它,但我注意到一些非常奇怪的东西。

UI 是从一个支持模型更新的;当模型发生变化时,我会在后台线程中重新计算模型,然后在 UI 线程上,将更新后的模型传递给各个组件以重新显示它们的信息。传递模型并进行所有(例如)textview.setText 调用大约需要 200-300 毫秒。但是,在更新功能完成后,UI 实际上最多 5 秒内不会更新。

我使用 ddms 中的方法分析工具来查看发生了什么,看起来在更新完成后的几秒钟内正在进行大量的测量和布局调用 - 我在几个地方覆盖了 onLayout,它似乎甚至设置只有一个值会导致整个 UI 被重新测量和布局。

所以我的问题是这是否正常;我可以看到更新需要一些时间,但 5 秒似乎很长。应用程序启动时显示 UI 可能需要几秒钟,所以我想知道 UI 是否太复杂。这是在带有 Android 4.0.4 的 Galaxy Tab 10.1 上。

谢谢

4

1 回答 1

0

事实证明,layout_weight 可能非常昂贵。应用程序的主面板由同一个自定义视图的两个实例组成,使用 layout_weight 将其分成两半:

<LinearLayout ...>
    <CustomView 
        android:layout_height="match_parent"
        android:layout_width="0dp"
        android:layout_weight="1" />
    <CustomView 
        android:layout_height="match_parent"
        android:layout_width="0dp"
        android:layout_weight="1" />
</LinearLayout>

我在整个应用程序中坚持了一些计时方法,并与层次结构查看器一起发现,在布局期间,对于每个对线性布局的 onMeasure 调用,onMeasure 在每个自定义视图上都被调用了 4 次。每个 onMeasure 调用大约需要 300-400 毫秒(正如我提到的,这是一个复杂的布局),这导致整个视图实际布局需要 3 秒以上。

任何时候视图发生变化(比如当编辑文本添加了一些文本)时,自定义视图的宽度都会根据权重进行更新。由于我只是使用权重来设置设备上的初始大小,并且每个自定义视图都无法调整其大小(因为它们都是屏幕宽度的一半),我删除了自定义视图上的 layout_weight 属性并添加了这对 onCreate 中的代码:

int halfScreenWidth = ...;
for(View v : new View[]{customViewA, customViewB})
{
    LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) v.getLayoutParams();
    lp.width = halfScreenWidth;
    v.setLayoutParams(lp);
}

此更改将每个自定义视图的 onMeasure 调用次数从 4 次减少到 2 次,节省了大量资金。所以这里学到的教训是,如果视图在运行时不需要调整大小,最好在代码中计算宽度,而不是依赖 XML 中的 layout_weight。

于 2013-04-28T23:45:38.980 回答