使用canvas.drawBitmap的Android动态壁纸是慢的方法

时间:2013-07-31 20:08:43

标签: android performance android-canvas live-wallpaper drawbitmap

我本周刚开始进行Android编程,并且正在制作动态壁纸。

我有2个图像,背景图像(720x1280 png)和一个滑动条(2276x290 png),在右侧环路中从右向左滑动。我的问题是我只能以每帧1 px的大约3-4fps滑动(在我的实际手机上,在AVD上我得到大约1 / 3fps),这对于动态壁纸来说是不稳定的。到目前为止,代码工作正常但速度慢。

如果有人知道一种方法可以更快地获得“很多”,那将是非常好的。

我的代码:

private class WEngine extends Engine {
    private final Handler handler = new Handler();
    private final Runnable drawRunner = new Runnable() {
        @Override
        public void run() {
            draw();
        }

    };
    private Paint paint = new Paint();
    private int width;
    int height;
    private boolean visible = true;
    int x = -1;
    int x2 = 0;
    int y = -1;

    public WEngine() {
        SharedPreferences prefs = PreferenceManager
                .getDefaultSharedPreferences(WService.this);
        handler.post(drawRunner);

    }

    @Override
    public void onVisibilityChanged(boolean visible) {
        this.visible = visible;
        if (visible) {
            handler.post(drawRunner);
        } else {
            handler.removeCallbacks(drawRunner);
        }
    }

    @Override
    public void onSurfaceDestroyed(SurfaceHolder holder) {
        super.onSurfaceDestroyed(holder);
        this.visible = false;
        handler.removeCallbacks(drawRunner);
    }

    @Override
    public void onSurfaceChanged(SurfaceHolder holder, int format,
            int width, int height) {
        this.width = width;
        this.height = height;
        super.onSurfaceChanged(holder, format, width, height);
    }

    private void draw() {
        SurfaceHolder holder = getSurfaceHolder();
        Canvas canvas = null;
        Resources res = getResources();
        Bitmap backgroundimg = BitmapFactory.decodeResource(res, R.drawable.background);
        Bitmap slidebarimg = BitmapFactory.decodeResource(res, R.drawable.slidebar);

        try {
            canvas = holder.lockCanvas();
            canvas.drawBitmap(backgroundimg, 0, 0, paint);
            if (canvas != null) {
                if (x<0 && y<0) {
                     x = 0;
                     y = Math.round(height / 2);
                 } else {
                     x -= 1;
                 }

                if (x - width < -height * 1.778125) {
                    x2 -= 1; 
                }

                if (x < -height * 1.778125) {
                    x = x2;
                    x2 = 0;
                }

                canvas.drawBitmap(slidebarimg, x, y, paint);

                if (x2 < 0) {
                    canvas.drawBitmap(slidebarimg, x2, y, paint);
                }
            }
        } finally {
            if (canvas != null)
                holder.unlockCanvasAndPost(canvas);

        }

        handler.removeCallbacks(drawRunner);
        handler.postDelayed(drawRunner, 30);
    }
}

编辑:

将图像更改为jpg文件后,我得到大约6 fps,但这仍然有点慢。

编辑2:

我刚才发现使用.lockCanvas()时无法进行hardwareaccceleration 还有另一种方法可以在livewallpaper(surfaceview)上绘制提供硬件加速的图像吗?

2 个答案:

答案 0 :(得分:1)

private void draw() {
    ...
    Bitmap backgroundimg = BitmapFactory.decodeResource(res, R.drawable.background);
    Bitmap slidebarimg = BitmapFactory.decodeResource(res, R.drawable.slidebar);
    ...

不要这样做。如果你在每一帧中解码位图,它会变慢。非常慢。如果你是硬件加速没关系也没关系。将它们解码一次,然后在每一帧上绘制

答案 1 :(得分:0)

OpenGl硬件纹理大小限制。在新设备中,它主要是2048px。尽量保持最大化。 (HW accelerated activity - how to get OpenGL texture size limit?) 还要确保应用程序中的硬件加速已启用 http://developer.android.com/guide/topics/graphics/hardware-accel.html