Android 部分失效在硬件加速时绘制整个视图

Android partial invalidation draws the entire view while hardware accelerated

我写了一个 Activity,它只显示一个自定义视图。

视图很简单,绘制随机颜色并使较小的区域无效,然后绘制随机颜色并使更小的区域无效,等等...

预期的结果应该是 this。它通过使用软件渲染和 getClipBounds() returns 我刚刚传递到无效的区域运行良好。但是当启用硬件加速时,整个视图总是用新颜色重绘,getClipBounds() return 整个视图区域。

我知道有些帖子像 this and this。答案说 getClipBounds() return 是整个视图区域的硬件加速,但只有与脏区域相交的区域才会被重绘。

有什么不对的地方或者我的理解有误吗?

public void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    // random color
    int color = Color.rgb((int) (Math.random() * 255),
            (int) (Math.random() * 255), (int) (Math.random() * 255));

    canvas.drawColor(color);

    canvas.getClipBounds(rect);

    // smaller dirty region
    invalidate(0, 0, rect.width() - 1, rect.height() - 1);
}

不幸的是,这是 Android 中硬件加速的限制,至少从 Android 开始是这样 5. invalidate rect 被忽略,整个视图总是重绘,需要你绘制整个区域。如果您尝试只绘制视图的一部分,之前在视图中绘制的任何其他内容都将消失。

我读过一些帖子,其中声称 Android 不会重新渲染整个视图,只会重新渲染发生变化的部分,但这似乎是错误的,因为当我尝试只渲染被更改的区域时在我传递给无效的矩形中,视图的其余部分消失了。如果 Android 确实只重新渲染了更改的区域,那么我希望视图中的自定义绘图的其余部分保持可见。

iOS 的 drawRect 方法和 setNeedsDisplayInRect 具有更好的性能。我原以为 Android 会以同样的方式工作,但遗憾的是它没有。