0

我有一个动态壁纸,它通过将每一帧绘制到画布上来运行循环动画。我有一张图片,大小与屏幕的确切尺寸一致。我有一组 400 个帧,大小正好适合屏幕底部三分之一;这是动画发生的地方。这是显示它们的代码:

public void updateBG() {
    mHandler.removeCallbacks(mUpdateDisplay);
    if (mVisible) {
        mHandler.postDelayed(mUpdateDisplay, 40);
    }

    if (imagesLoaded < totalFrames) {
        ShowLoadingProgress();
    } else {
        SurfaceHolder holder = getSurfaceHolder();
        Canvas c = null;
        try {
            c = holder.lockCanvas();
            if (c != null) {
                Paint p = new Paint();
                p.setAntiAlias(true);
                c.drawRect(0, 0, c.getWidth(), c.getHeight(), p);
                Rect destinationRect = new Rect();
                destinationRect.set(0, 0, canvasWidth, canvasHeight);


                if (animStartX > 0 || animEndX > 0 || animStartY > 0 || animEndY > 0) {
                    c.drawBitmap(BitmapFactory.decodeByteArray(bitmapArray[totalFrames], 0, bitmapArray[totalFrames].length), null, destinationRect, p);
                    Rect destinationRectAnim = new Rect();
                    destinationRectAnim.set(animX, animY, animX+animWidth, animY+animHeight);
                    c.drawBitmap(BitmapFactory.decodeByteArray(bitmapArray[bgcycle], 0, bitmapArray[bgcycle].length), null, destinationRectAnim, p);
                } else {
                    c.drawBitmap(BitmapFactory.decodeByteArray(bitmapArray[bgcycle], 0, bitmapArray[bgcycle].length), null, destinationRect, p);
                }

            }
        } finally {
            if (c != null)
                holder.unlockCanvasAndPost(c);
        }
        bgcycle++;
    }
}

此代码在 Xperia Ion(双核 1.5 GHz cpu)上以大约 10-12 FPS 的速度运行,而在旧设备上则更差。当我以屏幕分辨率的一半保存整个帧时,情况会好得多。当我开始在屏幕分辨率下使用全帧时,它实际上变得更糟了(这应该消除了在每一帧上插值的需要)。当我开始使用这段代码时,情况变得更糟,它编写了两个位图(大概是因为它无法保存上次运行的画布的上半部分)。

我该如何优化呢?我宁愿不保存完整的帧,因为只保存每一帧的动画部分确实可以减少内存使用量。这里感觉有些不对劲,特别是考虑到它背后有 3GHz 的功率运行。我曾经在 450 MHz Pentium III 上看电影。有什么明显的我做错了吗?即使尺寸正确,手机是否仍在尝试插入图像?

4

1 回答 1

3

您正在对每一帧的位图进行解码,这很昂贵,并且会产生会触发 GC 的垃圾。您还使用软件渲染进行渲染。以下是您的解决方案,按顺序排列:

  • 不要重新解码每一帧的位图
  • 重用位图对象(请参阅 BitmapFactory.Options.inBitmap)
  • 使用硬件加速(直接渲染到 View 而不是 SurfaceView。)软件插值非常昂贵。
于 2013-08-16T20:50:28.237 回答