2

In my interface, the user selects from a variable number of songs, and when a song is selected, I need to display the relevant background image. 用户需要在加载图像时保持对界面的控制,并且仍然可以更改歌曲。

我目前这样做的方式是使用 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.5mb 内存分配,我使用 bitmapfactory 选项:

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

绝对 - 任何建议将不胜感激,我一直在寻找关于回收位图、归零、GC、尝试使用可清除位图的方法。

4

1 回答 1

4

您可以尝试使用互斥锁序列化调用,以便只执行一个操作(即使它由于某种原因被取消)?请参阅下面的一个非常基本的方法。显然,您可以在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 回答