如何取消运行 BitmapFactory.decodeFile() 的 AsyncTask 并进行清理
在我的界面中,用户从可变数量的歌曲中进行选择,当选择一首歌曲时,我需要显示相关的背景图像。 用户需要在加载图像时保持对界面的控制,并且仍然能够更改歌曲。
我目前执行此操作的方法是使用 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;
绝对-任何建议将不胜感激,我已经搜索了无数关于回收位图、清空、GCing、尝试使用可清除位图的信息。
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.
The user needs to keep control of the interface while the images are loading, and still be able to change song.
The way I currently do this is using an AsyncTask.
I am executing it using:
if (LoadBG!=null&&!LoadBG.isCancelled())
LoadBG.cancel(false);
LoadBG = new loadBG();
LoadBG.execute((Object) diff.BGPath);
attempting to cancel the previous task if it is still running and creating it anew.
The task code does the bitmap loading:
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;
}
I've made quite a mess of recycling, nulling, running GC, all attempting to cancel the current task so that the newly created one will have enough memory for available for allocation,but whatever I try, I always get outofmemory exceptions when attempting to run too many too soon (about 4/5 times)
The images are 1024x768 jpg files, and ask for 1.5mb memory allocation, i use the bitmapfactory options:
opts.inPreferredConfig = Bitmap.Config.RGB_565;
opts.inPurgeable = true;
opts.inSampleSize = 1;
Absolutely -any- advice would be appreciated, I've searched to no end about recycling bitmaps, nulling, GCing, attempting to use purgeable bitmaps.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您是否可以尝试使用互斥体序列化调用,以便仅执行一个操作(即使由于某种原因被取消)?请参阅下面的非常基本的方法。显然,您可以在 doInBackground 方法中进行更多选择性锁定,但您明白了。
Can you try to serialize the calls with a Mutex, so that only one operation (even if it is being cancelled for some reason) executes? See a very rudimentary approach below. Obviously you could do more selective locking within the doInBackground method, but you get the picture.