3

我最近注意到我的应用程序存在严重的性能问题。我基本上有以下布局...... 在此处输入图像描述

描述
简而言之,有一个ViewPager将 3 RelativeLayouts 保存为页面的 a。在每个页面内都有一些TextViews。我最近注意到,当我在上面输入以执行快速 SQL 查询以自动完成时EditText,会出现很多延迟。TextWatcher当我输入文本时,我的 HTC One M8 卡顿和滞后,但我知道查询速度并不慢,因为我测量查询只需要大约 7 毫秒。

我使用了方法分析、Systrace 和普通的旧Log调试,并得出结论,每次我在 A、B 和 C 中的 s上进行的EditText大约1,700次调用中键入一个字符。累积起来,只有大约 15 个独立的 s页面。我注意到每个都被调用了数百次,而不是像通常那样只调用一次或两次。onMeasureTextViewRelativeLayoutTextViewonMeasure

问题
我不知道为什么EditText在页面 B 中输入会导致TextView页面 A 和 C 中的其他 s 也被“重新测量”。更重要的是,是否有人对为什么onMeasure如此频繁地被调用有见解?而且,有谁知道显着减少调用次数的解决方案onMeasure

细节
这可能会有所帮助:我实际上能够onMeasure通过删除 2 将调用次数减少到大约 900,RelativeLayout这可能表明onMeasure调用的传播开始于ViewPager.

4

1 回答 1

7

虽然我没有足够的信息来确定具体问题,但总的来说,我可以告诉你发生了什么:

对根视图的measure调用会导致对树下的每个子视图的调用measure,依此类推。

假设称为“当前视图”的视图,在要求其每个子视图测量自己之后,决定没有足够的空间容纳所有子视图。它会要求他们每个人再次测量自己,建议最大尺寸。然后,假设名为“Relative Layout B”的视图根据指定的最大值从根本上改变了它的大小。因为变化如此之大,“当前观点”必须再问每个孩子一次。这个循环很容易需要更多的迭代来解决。

当“当前视图”决定其大小时,它会向“View Pager”报告。假设“View Pager”没有足够的空间容纳它的三个视图,并且不得不要求他们重新测量,最大值。我们现在至少有 20 次调用 TextView 的onMeasure. 如果 ViewPager 上面的每个其他视图都迭代了几次,很快你就会开始看到大数字。

正如您已经指出的那样,最好的解决方案是减少该树的深度。或者,您可以使用具有更简单测量算法的布局管理器(FrameLayout、LinearLayout)

不过1500也不少。其中一种观点是做一些奇怪的事情。使用 DDMS 套件中的 TreeView 工具,您应该能够非常简单地识别它。在 Eclipse 中,它被称为“TreeView”。在 Studio 中,单击 Android 图标并切换到 Hierarchy View 透视图。您也可以从命令行,从 SDK 工具目录运行它。

补充: 如果在运行时将 Hierarchy Viewer 连接到应用程序,您将在其中一个窗格中看到整个视图树。树中的每个节点将在底部有三个彩色橡皮糖。第一个胶滴代表测量阶段。如果胶滴是绿色的,则该视图的测量阶段很快。如果它是黄色的,则该节点位于布局中前 50 个百分位的节点中。如果它是红色的,它是布局中最慢的。

您应该能够沿着黄色的踪迹到达有问题的视图。

于 2014-08-15T18:27:22.667 回答