我有一个列表视图,它可能有无限滚动加载的无限项目。
列表视图中的每个项目都有一个或两个我正在懒洋洋地加载的图像。
一切都很好,但当我滚动很长时间,它崩溃了,这在日志猫
08-07 15:26:25.231: E/AndroidRuntime(30979): FATAL EXCEPTION: Thread-60
08-07 15:26:25.231: E/AndroidRuntime(30979): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
08-07 15:26:25.231: E/AndroidRuntime(30979): at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
08-07 15:26:25.231: E/AndroidRuntime(30979): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:493)
08-07 15:26:25.231: E/AndroidRuntime(30979): at com.test.android.helper.LazyImageLoader.decodeFile(LazyImageLoader.java:171)
08-07 15:26:25.231: E/AndroidRuntime(30979): at com.test.android.helper.LazyImageLoader.getBitmap(LazyImageLoader.java:112)
08-07 15:26:25.231: E/AndroidRuntime(30979): at com.test.android.helper.LazyImageLoader.access$2(LazyImageLoader.java:106)
08-07 15:26:25.231: E/AndroidRuntime(30979): at com.test.android.helper.LazyImageLoader$ImageLoader.run(LazyImageLoader.java:197)
在我的lazy image loader中,我将位图存储在WeakHashMap
中。所以垃圾收集器应该收集位图,对吗?
我懒惰的图像加载器的工作原理是这样的。
我使用url和对Imageview的引用从我的适配器调用displayImage()
public void displayImage(String url, ImageView imageView, int defaultImageResourceId){
latestImageMetaData.put(imageView, url);
if(weakhashmapcache.containsKey(url)){
imageView.setImageBitmap(weakhashmapcache.get(url));
}
else{
enqueueImage(url, imageView, defaultImageResourceId);
imageView.setImageResource(defaultImageResourceId);
}
}
因此,如果我在缓存中找到图像,我会直接设置它,否则我会使用函数enqueueImage()
将其排队。
private void-enqueueImage(字符串url,ImageView-ImageView,int-defaultImageResourceId){Image-Image=new-Image(url,ImageView,defaultImageResourceId);downloadqueue.add(Image); // downloadQueue是一个阻塞队列,等待添加图像//如果队列即将满,则删除队列中前面的元素,因为它们无论如何都不可见迭代器迭代器=downloadQueue。迭代器();while(iterator.hasNext()
And my image loader thread is this -
class ImageLoader extends Thread {
public void run() {
Image firstImageInQueue;
try {
while((firstImageInQueue = downloadQueue.take()) != SHUTDOWN_TOKEN)
{
Bitmap imageBitmap = getBitmap(firstImageInQueue.url);
if(imageBitmap != null){
weakhashmap.put(firstImageInQueue.url, imageBitmap);
BitmapDisplayer displayer = new BitmapDisplayer(imageBitmap, firstImageInQueue.imageView, firstImageInQueue.url, firstImageInQueue.defaultImageResourceId);
Activity activity = (Activity)firstImageInQueue.imageView.getContext();
activity.runOnUiThread(displayer);
}
}
}
catch (InterruptedException e) {
e.printStackTrace();
}
finally {
imageLoaderTerminated = true;
}
}
}
getBitmap()
只是从url中获取图像并将其解码为位图对象。BitmapDisplayer
只是一个Runnable,它将图像设置为线程上UI图像视图。
我做错了什么?
尝试通用图像加载器
这是一个开源项目,他们有关于如何使用它的博客文章。我已经在几个项目中使用过它,即使在长长的列表中我也没有问题。
享受!!
这是一场噩梦,几天后
不要将所有位图都存储在缓存中。保持它在磁盘缓存和内存缓存之间交换。存储的位图数量取决于通过调用
int memClass=((活动管理器)上下文。getSystemService(Context.ACTIVITY_SERVICE))。getMemoryClass()
我使用了
LruCache
而不是WeakHashMap
缓存。LruCache
在支持包中可用。用LruCache
替换现有的WeakHashMap
实现非常容易。Android在缓存位图上也有一个漂亮的留档。
Jake Wharton的
DiskLruCache
是管理磁盘缓存的好方法。
如果不需要,不要下载巨大的位图。试着买一个刚好适合你需要的尺码。
使用BitmapFactory。选项您可以在图像质量上做出一些权衡,以便在内存缓存中保存更多图像。
如果你认为我们还有什么可以做的,请补充。
在我的应用程序中,当我试图启动它时,会强制关闭,错误指向“setContentView(R.layout.Menu);”布局的一部分。在XML文件中,它在我的布局中显示“OutOfMemoryError”图像视图。我真的很困惑。请引导我进一步行动。 编辑: 我的应用程序使用数据库,第一次解析一些XML数据并插入Sqlite数据库。我的Outofmemory问题只在第一次出现。第二次效果很好。我试过
问题内容: 我正在使用ListView来显示一些图像和与这些图像相关的标题。我正在从互联网上获取图像。有没有一种方法可以延迟加载图像,以便在显示文本时不阻止UI并在下载图像时显示它们? 图像总数不固定。 问题答案: 这是我创建的用于保存应用程序当前正在显示的图像的内容。请注意,此处使用的“ Log”对象是我在Android内部最终Log类周围的自定义包装。
问题内容: 这是一个非常常见的场景:在ListView中显示必须从Internet下载的图像。 现在,我有一个用于ArrayView的自定义子类ArrayAdapter。在ArrayAdapter的getView()实现中,我产生了一个单独的线程来加载图像。加载完成后,它将查找适当的ImageView并使用ImageView.setImageDrawable()设置图像。因此,我使用的解决方案与此
Flask 通常配合装饰器使用,装饰器使用非常简单,而且使您可以将 URL 和处理它的函数 放在一起。然而这种方法也有一种不足: 这就意味着您使用装饰器的代码必须在前面导入, 否则 Flask 将无法找到您的函数。 这对于需要很快导入的应用程序来说是一个问题,这种情况可能出现在类似谷歌的 App Engine 这样的系统上。所以如果您突然发现您的引用超出了这种方法可以处理 的能力,您可以降级到中央
问题内容: 我正在开发一个eshop。在基于类别的产品页面上,我放置了一些基于javascript的过滤器。但是,如果类别具有很多产品,则会出现问题。该链接具有与我相似的功能… 这个页面多么缓慢,却超过2mb !!! 对我来说,每个产品都需要一半的K字节,但是图像是个问题。.因此,我正在寻找如何延迟加载图像的方法。由于与该网站不同,我的页面具有分页功能,因此我认为加载仅对页面可见的图像是一种解决方
我有一个列表视图,它显示带有缩略图图像的视频,我使用光标适配器(使用ContentProvider获取)。问题是随着列表项数量的增加,列表视图性能变得非常差。请让我知道使其延迟加载的最佳方法。 新:我终于找到了一些解决办法。这对我来说很好。如果你有什么建议,请告诉我。我的新代码在这里。(它使用具有生产者-消费者模式和bacground线程的堆栈进行处理) @覆盖公共空bindView(视图视图、上