Android Canvas.drawBitmap()间歇性变慢,导致白色闪烁

Android Canvas.drawBitmap()间歇性变慢,导致白色闪烁,android,android-canvas,Android,Android Canvas,我正在制作带有滚动背景的实时壁纸。我有两个位图对象,为了在下一帧中保留先前绘制的像素,我在它们之间交替使用。我在画布顶部画一条新线,然后调用drawBitmap将其余像素复制到画布上 我正在用一个可运行的物体做重物。它执行所有需要的复制和计算,然后锁定画布,在支架上输入一个同步块,并对canvas.drawBitmap(位图、rect、rect、paint)进行一次调用。偶尔屏幕上会出现白色闪烁,这似乎与高CPU活动相关。在使用traceview时,我发现drawBitmap操作,特别是Canv

我正在制作带有滚动背景的实时壁纸。我有两个位图对象,为了在下一帧中保留先前绘制的像素,我在它们之间交替使用。我在画布顶部画一条新线,然后调用drawBitmap将其余像素复制到画布上

我正在用一个可运行的物体做重物。它执行所有需要的复制和计算,然后锁定画布,在支架上输入一个同步块,并对canvas.drawBitmap(位图、rect、rect、paint)进行一次调用。偶尔屏幕上会出现白色闪烁,这似乎与高CPU活动相关。在使用traceview时,我发现drawBitmap操作,特别是Canvas.native_drawBitmap(),比正常操作花费的时间要长得多。通常它在2-4毫秒内完成,但当我看到白色闪光时,它可能需要10到100毫秒

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;
主要目标是不要对用于系统画布渲染的变量进行长时间写入,只需更改对象引用即可

希望这有帮助