在我的界面中,用户从可变数量的歌曲中进行选择,当选择了一首歌曲时,我需要显示相关的背景图像。 用户需要在加载图像时保持对界面的控制,并且仍然能够改变歌曲。
我目前的做法是使用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,尝试使用可清除位图的结果。
答案 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]
}
}