2

私のインターフェースでは、ユーザーが可変数の曲から選択し、曲が選択されたときに、関連する背景画像を表示する必要があります。ユーザーは、画像の読み込み中もインターフェースを制御し続け、曲を変更できるようにする必要があります。

私が現在これを行う方法は、AsyncTaskを使用することです。

私はそれを使用して実行しています:

if (LoadBG!=null&&!LoadBG.isCancelled())
LoadBG.cancel(false);

LoadBG = new loadBG();
LoadBG.execute((Object) diff.BGPath);

前のタスクがまだ実行中の場合はキャンセルを試み、新しく作成します。

タスクコードはビットマップの読み込みを行います。

protected Boolean doInBackground(Object... param) {

        String pathName = param[0].toString();
        if (!pathName.equals(gfxStore.currentBGPath)) {

            currentBGLoaded = false;
            while(overlayOpacity!=255)
                Thread.yield();
            //set current bg
            if (this.isCancelled())
                return true;
            Bitmap d;
            try
            {
            d = gfxStore.factory.decodeFile(pathName,gfxStore.opts);
            }
            catch (OutOfMemoryError e)
            {
                System.gc();
                return true;
            }
            if (this.isCancelled())
            {
                d.recycle();
                d = null;
                System.gc();
                return true;
            }
            Bitmap s;
            try
            {
            s = gfxStore.scaleImageForCanvas(canvasWidth, canvasHeight,d );
            }
            catch (OutOfMemoryError e)
            {
                //XXX uuuugh
                System.gc();
                return true;
            }
            if (this.isCancelled())
            {
                d.recycle();
                d=null;
                s.recycle();
                s=null;
                System.gc();
                return true;
            }
            d.recycle();
            d=null;
            System.gc();
            gfxStore.currentBG = s;
            gfxStore.currentBGPath = pathName;
            wasChange = true;
        }
        else
            wasChange=false;
        return true;
    }

私はリサイクル、ヌル、GCの実行をかなり混乱させました。すべて、現在のタスクをキャンセルして、新しく作成されたタスクに割り当てに使用できる十分なメモリを確保しようとしましたが、何をしようとしても、しようとすると常にメモリ不足の例外が発生します。実行が早すぎる(約4/5回)

画像は1024x768のjpgファイルで、1.5 MBのメモリ割り当てを要求します。私は、bitmapfactoryオプションを使用します。

opts.inPreferredConfig = Bitmap.Config.RGB_565;
    opts.inPurgeable = true;
    opts.inSampleSize = 1;

絶対に-どんなアドバイスでもありがたいです、私はビットマップのリサイクル、ヌル、GCing、パージ可能なビットマップの使用の試みについて果てしなく検索しました。

4

1 に答える 1

4

Mutexを使用して呼び出しをシリアル化して、(何らかの理由でキャンセルされている場合でも)1つの操作のみが実行されるようにすることはできますか?以下の非常に基本的なアプローチを参照してください。明らかに、 doInBackgroundメソッド内でより選択的なロックを行うことができますが、全体像を把握できます。

static class DecodeLock extends Object {
}
static public DecodeLock lockObject = new DecodeLock();

// ...

protected Boolean doInBackground(Object... param) {
   synchronized (lockObject) {
      String pathName = param[0].toString();
          if (!pathName.equals(gfxStore.currentBGPath)) {

          //[..snip]
    }
 }
于 2011-04-20T15:42:08.250 に答える