批量图像下载时出现 OutOfMemoryError
我有一个很大的对象列表,所有对象都有一个指向其图像的路径“例如 http://www .google.com/image.jpg”,我需要下载图像并将可绘制对象保存到对象中。
我使用的是 AsyncTask,但即使我使用自己的线程,我总是会遇到“OutOfMemoryError”在列表中的某个任意点。图像的大小永远不会超过 82Kb(这对于 Android 平板电脑来说太大了吗?),但我认为图像的绝对数量会导致整个过程失败。
这是我目前正在做的事情。
class DownloadImageTask extends AsyncTask<ArrayList<Item>, Void, Void> {
private static int num =1;
@Override
protected Void doInBackground(ArrayList<Item>... items) {
try {
if(items.length == 0)
return null;
HttpURLConnection connection;
InputStream input;
for(ArrayList<Item> itemlist : items) {
for(Item i : itemlist) {
Log.d(JusTouchMenu.TAG,"[Item]Image request to url:"+i.getImagePath());
try {
connection = (HttpURLConnection)new URL(i.getImagePath()).openConnection();
connection.setRequestProperty("User-agent","Mozilla/4.0");
connection.connect();
input = connection.getInputStream();
i.setImage(new BitmapDrawable(BitmapFactory.decodeStream(input)));//Requires a drawable
connection.disconnect();
} catch(Exception e) {Log.e(JusTouchMenu.TAG,"[Item]Unable to download image @ '"+i.getImagePath()+"'",e);}
Log.v(JusTouchMenu.TAG, "[Item]Image decoded @ '"+i.getImagePath()+"' #"+num++);
for(Tag pt : i.tags()) {
Log.d(JusTouchMenu.TAG,"[Item->Tag]Image request to url:"+pt.getImagePath());
try {
connection = (HttpURLConnection)new URL(pt.getImagePath()).openConnection();
connection.setRequestProperty("User-agent","Mozilla/4.0");
connection.connect();
input = connection.getInputStream();
pt.setImage(new BitmapDrawable(BitmapFactory.decodeStream(input))); //Requires a drawable
connection.disconnect();
} catch(Exception e) {
Log.e(JusTouchMenu.TAG,"[Item->Tag]Unable to download image @ '"+i.getImagePath()+"'",e);
}
Log.v(JusTouchMenu.TAG, "[Item->Tag]Image decoded @ '"+pt.getImagePath()+"' #"+num++);
}
}
}
} catch(Exception e) {
Log.e(JusTouchMenu.TAG,"Error decoding image inside AsyncTask",e);
}
return null;
}
谢谢!
I have a large list of objects, all of whom have a path to their image "ex. http://www.google.com/image.jpg" and I need to download the image and save the drawable to the object..
I was using AsyncTask, but even if I use my own threads I always end up with 'OutOfMemoryError' at some arbitrary point in the list. The images are never larger than 82Kb (Is this too big for android tablets?) in size, but I think the sheer number of images is causing the process as a whole to fail.
Here is what I'm currently doing.
class DownloadImageTask extends AsyncTask<ArrayList<Item>, Void, Void> {
private static int num =1;
@Override
protected Void doInBackground(ArrayList<Item>... items) {
try {
if(items.length == 0)
return null;
HttpURLConnection connection;
InputStream input;
for(ArrayList<Item> itemlist : items) {
for(Item i : itemlist) {
Log.d(JusTouchMenu.TAG,"[Item]Image request to url:"+i.getImagePath());
try {
connection = (HttpURLConnection)new URL(i.getImagePath()).openConnection();
connection.setRequestProperty("User-agent","Mozilla/4.0");
connection.connect();
input = connection.getInputStream();
i.setImage(new BitmapDrawable(BitmapFactory.decodeStream(input)));//Requires a drawable
connection.disconnect();
} catch(Exception e) {Log.e(JusTouchMenu.TAG,"[Item]Unable to download image @ '"+i.getImagePath()+"'",e);}
Log.v(JusTouchMenu.TAG, "[Item]Image decoded @ '"+i.getImagePath()+"' #"+num++);
for(Tag pt : i.tags()) {
Log.d(JusTouchMenu.TAG,"[Item->Tag]Image request to url:"+pt.getImagePath());
try {
connection = (HttpURLConnection)new URL(pt.getImagePath()).openConnection();
connection.setRequestProperty("User-agent","Mozilla/4.0");
connection.connect();
input = connection.getInputStream();
pt.setImage(new BitmapDrawable(BitmapFactory.decodeStream(input))); //Requires a drawable
connection.disconnect();
} catch(Exception e) {
Log.e(JusTouchMenu.TAG,"[Item->Tag]Unable to download image @ '"+i.getImagePath()+"'",e);
}
Log.v(JusTouchMenu.TAG, "[Item->Tag]Image decoded @ '"+pt.getImagePath()+"' #"+num++);
}
}
}
} catch(Exception e) {
Log.e(JusTouchMenu.TAG,"Error decoding image inside AsyncTask",e);
}
return null;
}
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您想一次获取多少张这样的图像?你如何使用它们?
您可能应该考虑使用 Gallery 或 GridView 的功能,从而仅加载当前视图中的图像。您甚至可以花哨并缓存它们,以便滚动流畅。当您不可能一次显示所有图像时,尝试将所有图像加载到 ArrayList 中并不是一种适合移动设备的方法。
这里有一些关于缓存方法的不错的参考,但您可能应该根据需要从基本的图库或网格视图加载开始,然后添加缓存。
ListView 中的图像延迟加载
http://code.google.com/p/libs-for-android/wiki/ImageLoader
How many of these images are you trying to get at once? How are you using them?
You should probably consider using the capabilities of Gallery or GridView and thereby only be loading the images that are in view at the moment. You can even get fancy and cache them so scrolling is nice and smooth. Trying to load all of the images into an ArrayList when youre not likely to be able to display them all at once is not a mobile friendly approach.
Here are some decent references to caching approaches but you should probably get started with a basic gallery or grid view loading as needed and then add the caching on.
Lazy load of images in ListView
http://code.google.com/p/libs-for-android/wiki/ImageLoader