在自定义视图onDraw中使用硬件层

所以我想了解如何在自定义View中正确使用硬件加速(如果可用),并持续animation。 这是我的onDraw()的基本前提:

 canvas.drawColor(mBackgroundColor); for (Layer layer : mLayers) { canvas.save(); canvas.translate(layer.x, layer.y); //Draw that number of images in a grid, offset by -1 for (int i = -1; i < layer.xCount - 1; i++) { for (int j = -1; j < layer.yCount - 1; j++) { canvas.drawBitmap(layer.bitmap, layer.w * i, layer.h * j, null); } } //If the layer's x has moved past its width, reset back to a seamless position layer.x += ((difference * layer.xSpeed) / 1000f); float xOverlap = layer.x % layer.w; if (xOverlap > 0) { layer.x = xOverlap; } //If the layer's y has moved past its height, reset back to a seamless position layer.y += ((difference * layer.ySpeed) / 1000f); float yOverlap = layer.y % layer.h; if (yOverlap > 0) { layer.y = yOverlap; } canvas.restore(); } //Redraw the view ViewCompat.postInvalidateOnAnimation(this); 

我在onAttachedToWindow()启用硬件层,并在onAttachedToWindow()禁用它们,但我试图了解我是否实际使用它。 本质上,调用drawBitmap()i/j循环从不改变; 唯一改变的是Canvas翻译。 Bitmap是否会自动保存到GPU中作为背景纹理,或者是否有需要手动执行的操作?

Solutions Collecting From Web of "在自定义视图onDraw中使用硬件层"

你在哪个视图中准确设置View.LAYER_TYPE_HARDWARE ? 如果您在包含上面显示的绘图代码的视图上设置硬件层,则会导致系统执行大量的工作。 既然你只是绘制位图,你不需要在这里做任何事情。 如果您调用Canvas.drawBitmap() ,框架将代表您caching生成的OpenGL纹理。

然而,你可以优化你的代码多一点。 而不是调用drawBitmap() ,你可以使用子视图。 如果使用offset*()方法(或setX() / setY() )移动这些孩子,则框架将应用进一步的优化以避免再次调用draw()方法。

一般来说,硬件层应该被设置在绘制成本高昂的视图上,而且其内容不会经常变化(这与你正在做的事情完全相反)

您可以使用Android的Tracer for OpenGL ES来查看您的视图是否发出OpenGL命令。

来自developer.android.com

Tracer是一个在Android应用程序中分析OpenGL for Embedded Systems(ES)代码的工具。 该工具允许您捕获OpenGL ES命令和逐帧图像,以帮助您了解如何执行graphics命令。

还有一个关于Romain Guy的Android性能研究的教程,几乎一步一步地描述了它的使用。