在CustomView中连续绘制时性能不佳

Vij*_*Raj 13 performance android canvas surfaceview android-bitmap

使用案例:

我需要在我的视图上画出数百行和几段文字.我需要给出一个滚动效果,为此我捕获ACTION_MOVE事件并使用更新的点重绘所有行.为了得到欲望的结果,我尝试了不同的方法但没有按预期工作.

方法1

我做了一个扩展的自定义类View.所有绘图和计算都直接在我的onDraw()方法中完成.由于在onDraw()方法中完成了大量操作,因此应用程序的性能非常差.我甚至使用Profile GPU渲染检查了性能,我可以看到线条非常高.

方法2

我创建了一个Bitmap,在将所有行绘制到另一个线程中的位图后,我习惯postInvalidate()onDraw()方法中绘制位图:

mBufferedBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);   
mBufferedBitmap.eraseColor(Color.TRANSPARENT);    
Canvas mBufferedCanvas = new Canvas(mBufferedBitmap);               
drawLines(mBufferedCanvas)    
postInvalidate();
Run Code Online (Sandbox Code Playgroud)

由于我擦除了位图上的所有先前绘图并使用更新的点绘制新行,因此屏幕上会出现闪烁.

方法3

我尝试将自定义类扩展到SurfaceView另一个线程中的canvas对象上的所有操作.但由于SurfaceView使用CPU进行绘图操作,因此低配置手机的性能会很差.

谁能指导我如何以更好的性能完成这项任务?

Dav*_*son 7

可以使用您的方法1来实现良好的性能.

听起来接近您的用例的一个示例(绘制线条,一些文本以及手势移动上的这些更新)是MPAndroidChart.这是一个实现高性能的开源库(如果需要统计数据,请参阅以下比较)

要检查的Renderer类是类,因为它们包含onDraw(Canvas c)图表子类型中的代码绘制.您可以看到用于实现高性能的一些技巧:

  1. 不要在渲染循环中分配.相反,在循环外部分配并重用/循环变量.见LineChartRenderer 199行
  2. 使用缓冲.例如,在MPAndroidChart中,条形图中条形四个角的点被缓冲,缓冲区数组被重用.看BarBuffer课.
  3. 使用本机画布绘制功能(drawPath,drawLine等等)

有关优化渲染的完整提示列表,请参阅Android Performance Slow Rendering Guide