Systrace 显示 performTraversals 和 getDisplayList 需要很长时间

Systrace shows performTraversals and getDisplayList take a long time

我有一个 gridView,一次在屏幕上显示 20 个自定义组件(作为网格视图项)。滚动视图非常不稳定,我正在尝试确定原因。我的 systrace(如下所示)显示在 performTraversals 和 getDisplayList 上花费了大量时间(大约 40 毫秒),但我不知道它们在做什么。我为我的 onMeasure、onLayout 和 onDraw 添加了自定义跟踪。相比之下,这些都是 tiny

我不确定下一步该去哪里确定什么一直在占用...

所以这最终变得非常具体。问题是当 GridView 滚动时我需要使 GridView 中的项目无效,因为它们是需要重绘自身的自定义控件。在 GridView OnScroll 中,我正在调用 GridView.invalidateViews()。事实证明,这非常慢。我将其替换为以下内容:

for(int visiblePosition = 0; visiblePosition <= mGridView.getLastVisiblePosition() - mGridView.getFirstVisiblePosition(); visiblePosition++) {
    mGridView.getChildAt(visiblePosition).invalidate();
}

那个小循环比 invalidateViews 快得离谱。我没有查看代码来确定原因。

那么,我是如何确定这是问题所在的呢?所有这些花哨的工具都没有真正帮助。相反,我使用了一些不错的老式评论柔术。我不断削减滚动时发生的一切,这就是与众不同的那一行。我的帧从 ~50ms 到 ~8ms。