0

各フレームをキャンバスに描画してループアニメーションを実行しているライブ壁紙があります。画面の正確なサイズに合わせたサイズの画像が1つあります。画面の下 3 分の 1 にちょうど収まるサイズの 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 で実行され、古いデバイスではさらに悪化します。画面解像度の半分でフレーム全体を保存すると、はるかにうまくいきました。画面解像度でフル フレームを使用し始めたとき、実際にはさらに悪化しました (これにより、各フレームで補間する必要がなくなるはずでした)。その後、2 つのビットマップを書き込むこのコードを使い始めると、さらに悪化しました (おそらく、前回の実行からキャンバスの上半分を保存できないためです)。

これを最適化するにはどうすればよいですか?各フレームのアニメーション部分を保存するだけでメモリ使用量が大幅に削減されるため、フレーム全体を保存したくありません。特にこれが背後で 3 GHz の電力で実行されていることを考えると、ここで何かが本当に間違っているように感じます。私は 450 MHz の Pentium III で映画を見ていました。私が間違っていることは明らかですか?画像のサイズが正しく設定されていても、電話機はまだ画像を補間しようとしていますか?

4

1 に答える 1

3

フレームごとにビットマップをデコードしていますが、コストが高く、GC をトリガーするガベージが生成されます。また、ソフトウェア レンダリングを使用してレンダリングしています。解決策は次のとおりです。

  • フレームごとにビットマップを再デコードしない
  • ビットマップ オブジェクトを再利用します (BitmapFactory.Options.inBitmap を参照)。
  • ハードウェア アクセラレーションを使用します (SurfaceView ではなくビューに直接レンダリングします)。ソフトウェア補間は非常にコストがかかります。
于 2013-08-16T20:50:28.237 に答える