Android Canvas.drawBitmap()间歇性变慢,导致白色闪烁
我正在制作带有滚动背景的实时壁纸。我有两个位图对象,为了在下一帧中保留先前绘制的像素,我在它们之间交替使用。我在画布顶部画一条新线,然后调用drawBitmap将其余像素复制到画布上 我正在用一个可运行的物体做重物。它执行所有需要的复制和计算,然后锁定画布,在支架上输入一个同步块,并对canvas.drawBitmap(位图、rect、rect、paint)进行一次调用。偶尔屏幕上会出现白色闪烁,这似乎与高CPU活动相关。在使用traceview时,我发现drawBitmap操作,特别是Canvas.native_drawBitmap(),比正常操作花费的时间要长得多。通常它在2-4毫秒内完成,但当我看到白色闪光时,它可能需要10到100毫秒Android Canvas.drawBitmap()间歇性变慢,导致白色闪烁,android,android-canvas,Android,Android Canvas,我正在制作带有滚动背景的实时壁纸。我有两个位图对象,为了在下一帧中保留先前绘制的像素,我在它们之间交替使用。我在画布顶部画一条新线,然后调用drawBitmap将其余像素复制到画布上 我正在用一个可运行的物体做重物。它执行所有需要的复制和计算,然后锁定画布,在支架上输入一个同步块,并对canvas.drawBitmap(位图、rect、rect、paint)进行一次调用。偶尔屏幕上会出现白色闪烁,这似乎与高CPU活动相关。在使用traceview时,我发现drawBitmap操作,特别是Canv
private void draw() {
SurfaceHolder holder = getSurfaceHolder();
Canvas canvas = null;
prepareFrame();
try {
canvas = holder.lockCanvas();
synchronized (holder) {
if (canvas != null) {
drawFrame(canvas);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (canvas != null)
holder.unlockCanvasAndPost(canvas);
}
afterDrawFrame();
handler.removeCallbacks(drawRunner);
if (visible) {
handler.post(drawRunner);
}
}
在Runnable的run()
中调用draw()
函数
private void prepareFrame() {
num++;
if (num%2 == 0) {
mainBmp = mainBmp1;
mainCan.setBitmap(mainBmp1);
mainCan.drawBitmap(mainBmp2, source, destination, null);
} else {
mainBmp = mainBmp2;
mainCan.setBitmap(mainBmp2);
mainCan.drawBitmap(mainBmp1, source, destination, null);
}
}
prepareFrame()。称为source的Rect在底部比全屏大小少一行,而as destination在顶部比全屏大小少一行。prepareFrame()
private void drawFrame(Canvas can) {
can.drawBitmap(mainBmp, source, destination,null);
}
这个单一操作是在画布上进行的,同时保持锁定
private void afterDrawFrame() {
ca.calcNextRow();
mainBmp.setPixels(ca.getRow(), 0, canWidth, 0, 0, canWidth, 1);
}
然后,下一行新像素被绘制到内存中的一个位图上
我曾尝试使用drawBitmap()
的各种签名,但发现它们平均速度较慢,仍然会导致异常的白光闪烁
我的整体速度很棒。没有间歇性的闪光,它的工作非常好。有人对如何消除闪烁有什么建议吗?很难确切知道这里发生了什么,因为你没有包括一些中心变量的定义或使用,如“mainCan”或“ca”。一个更完整的源代码参考会更好
但是
可能发生的情况是,由于drawFrame(画布)在支架上是同步的,但是
handler.post(drawRunner);
如果不是,则会出现这样的情况,即您试图将mainBmp绘制到系统画布上,同时在PrepareName()中写入mainBmp
这个问题的最佳解决方案可能是某种双缓冲,您可以执行以下操作
1) Write to a temporary bitmap
2) Change the ref of that bitmap to the double buffer i.e. mainBmp = tempBitmap;
主要目标是不要对用于系统画布渲染的变量进行长时间写入,只需更改对象引用即可
希望这有帮助