如何取消运行BitmapFactory.decodeFile()和清理的AsyncTask

时间:2011-04-20 15:17:34

标签: android bitmap android-asynctask bitmapfactory

在我的界面中,用户从可变数量的歌曲中进行选择,当选择了一首歌曲时,我需要显示相关的背景图像。 用户需要在加载图像时保持对界面的控制,并且仍然能够改变歌曲。

我目前的做法是使用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,所有试图取消当前任务,以便新创建的任务将有足够的内存可供分配,但无论我尝试什么,我总是得到outofmemory异常当试图太快运行太多时(约4/5次)

图像是1024x768 jpg文件,并要求1.5mb内存分配,我使用bitmapfactory选项:

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

绝对-any-建议将不胜感激,我已经搜索到关于回收位图,归零,GCing,尝试使用可清除位图的结果。

1 个答案:

答案 0 :(得分:4)

您是否可以尝试使用Mutex序列化呼叫,以便只执行一次操作(即使由于某种原因被取消)?请参阅下面的一个非常基本的方法。显然你可以在 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]
    }
 }