【问题标题】:Android Live Wallpaper with canvas.drawBitmap is way to slow带有 canvas.drawBitmap 的 Android 动态壁纸是一种放慢速度的方法
【发布时间】:2013-08-02 03:43:04
【问题描述】:

我这周刚开始 android 编程,目前正在制作动态壁纸。

我有 2 个图像,背景图像 (720x1280 png) 和一个滑动条 (2276x290 png),它在一个循环中从右向左滑动。我的问题是我只能让它以大约 3-4fps 的速度滑动,每帧 1 像素(在我的实际手机上,在 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() 时无法进行硬件加速 是否有另一种方法可以在提供硬件加速的动态壁纸(surfaceview)上绘制图像?

【问题讨论】:

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


    【解决方案1】:
    private void draw() {
        ...
        Bitmap backgroundimg = BitmapFactory.decodeResource(res, R.drawable.background);
        Bitmap slidebarimg = BitmapFactory.decodeResource(res, R.drawable.slidebar);
        ...
    

    不要这样做。如果你在每一帧中解码位图,它会很慢。非常慢。无论您是否进行硬件加速都没有关系。将它们解码一次,然后在每一帧上绘制它们。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 我只是确保硬件加速已打开,但它没有在我的画布上使用(我在绘制滑动条位图之前添加了 if (canvas.isHardwareAccelerated()) 并且它没有绘制它)我还减少了 img尺寸为 576x1024 和 320x290 以确保,但它没有任何效果。 (c的小图除外)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多