Android图像缓存
从网络下载图像后如何缓存图像?
How can I cache images after they are downloaded from web?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
从网络下载图像后如何缓存图像?
How can I cache images after they are downloaded from web?
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(18)
我尝试过 SoftReferences,它们在 Android 中被过度回收,我觉得没有必要使用它们
I've tried SoftReferences, they are too aggressively reclaimed in android that I felt there was no point using them
正如 Thunder Rabbit 所建议的,ImageDownloader 是最适合这项工作的工具。我还在以下位置发现了该类的细微变化:
http://theandroidcoder。 com/utilities/android-image-download-and-caching/
两者的主要区别是ImageDownloader使用Android缓存系统,修改后的使用内部和外部存储作为缓存,保留缓存的图片无限期地或直到用户手动将其删除。作者还提到了Android 2.1的兼容性。
As Thunder Rabbit suggested, ImageDownloader is the best one for the job. I also found a slight variation of the class at:
http://theandroidcoder.com/utilities/android-image-download-and-caching/
The main difference between the two is that the ImageDownloader uses the Android caching system, and the modified one uses internal and external storage as caching, keeping the cached images indefinitely or until the user removes it manually. The author also mentions Android 2.1 compatibility.
这是乔的一个很好的接球。上面的代码示例有两个问题 - 一 - 响应对象不是 Bitmap 的实例(当我的 URL 引用 jpg 时,例如 http:\website.com\image.jpg,它是
org.apache.harmony.luni。 Internal.net.www.protocol.http.HttpURLConnectionImpl$LimitedInputStream)。
其次,正如 Joe 指出的,如果没有配置响应缓存,就不会发生缓存。 Android 开发人员只能滚动自己的缓存。这是一个这样做的示例,但它仅缓存在内存中,这实际上不是完整的解决方案。
http://codebycoffee.com/2010/06/29/using-responsecache -in-an-android-app/
URLConnection 缓存 API 描述如下:
http://download.oracle.com/javase/6/docs/technotes/ guides/net/http-cache.html
我仍然认为这是走这条路的一个不错的解决方案 - 但你仍然必须编写一个缓存。听起来很有趣,但我宁愿写功能。
This is a good catch by Joe. The code example above has two problems - one - the response object isn't an instance of Bitmap (when my URL references a jpg, like http:\website.com\image.jpg, its a
org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl$LimitedInputStream).
Second, as Joe points out, no caching occurs without a response cache being configured. Android developers are left to roll their own cache. Here's an example for doing so, but it only caches in memory, which really isn't the full solution.
http://codebycoffee.com/2010/06/29/using-responsecache-in-an-android-app/
The URLConnection caching API is described here:
http://download.oracle.com/javase/6/docs/technotes/guides/net/http-cache.html
I still think this is an OK solution to go this route - but you still have to write a cache. Sounds like fun, but I'd rather write features.
Android 官方培训部分对此有一个专门的条目: http://developer.android .com/training/displaying-bitmaps/cache-bitmap.html
该部分非常新,在提出问题时它不存在。
建议的解决方案是使用 LruCache。该类是在 Honeycomb 上引入的,但它也包含在兼容性库中。
您可以通过设置最大数量或条目来初始化 LruCache,它会自动对它们进行排序,并在超过限制时清理较少使用的条目。除此之外,它用作普通地图。
官方页面的示例代码:
以前 SoftReferences 是一个不错的选择,但现在不再是了,引用官方页面:
There is a special entry on the official training section of Android about this: http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html
The section is quite new, it was not there when the question was asked.
The suggested solution is to use a LruCache. That class was introduced on Honeycomb, but it is also included on the compatibility library.
You can initialize a LruCache by setting the maximum number or entries and it will automatically sort them your you and clean them less used ones when you go over the limit. Other than that it is used as a normal Map.
The sample code from the official page:
Previously SoftReferences were a good alternative, but not anymore, quoting from the official page:
考虑使用通用图像加载器库(作者:谢尔盖·塔拉塞维奇。它附带:
Universal Image Loader 允许对下载的图像进行详细的缓存管理,具有以下缓存配置:
UsingFreqLimitedMemoryCache
:最不频繁的 i> 当超过缓存大小限制时,使用的位图将被删除。LRULimitedMemoryCache
:当超出缓存大小限制时,最近使用的位图将被删除。FIFOLimitedMemoryCache
:当超过缓存大小限制时,采用先进先出规则进行删除。LargestLimitedMemoryCache
:当超过缓存大小限制时,最大位图将被删除。LimitedAgeMemoryCache
:当缓存对象的年龄超过定义值时,该对象将被删除。WeakMemoryCache
:仅对位图进行弱引用的内存缓存。一个简单的使用示例:
此示例使用默认的
UsingFreqLimitedMemoryCache
。Consider using Universal Image Loader library by Sergey Tarasevich. It comes with:
Universal Image Loader allows detailed cache management for downloaded images, with the following cache configurations:
UsingFreqLimitedMemoryCache
: The least frequently used bitmap is deleted when the cache size limit is exceeded.LRULimitedMemoryCache
: The least recently used bitmap is deleted when the cache size limit is exceeded.FIFOLimitedMemoryCache
: The FIFO rule is used for deletion when the cache size limit is exceeded.LargestLimitedMemoryCache
: The largest bitmap is deleted when the cache size limit is exceeded.LimitedAgeMemoryCache
: The Cached object is deleted when its age exceeds defined value.WeakMemoryCache
: A memory cache with only weak references to bitmaps.A simple usage example:
This example uses the default
UsingFreqLimitedMemoryCache
.对我来说真正有用的是在我的主类上设置 ResponseCache:
以及
在下载位图时。
http://practicaldroid.blogspot.com/2013/01/utilizing -http-response-cache.html
What actually worked for me was setting ResponseCache on my Main class:
and
when downloading bitmap.
http://practicaldroid.blogspot.com/2013/01/utilizing-http-response-cache.html
Google 的 libs-for-android 有一个很好的库,用于管理图像和文件缓存。
http://code.google.com/p/libs-for-android/
Google's libs-for-android has a nice libraries for managing image and file cache.
http://code.google.com/p/libs-for-android/
我已经为此苦苦挣扎了一段时间。使用软引用的答案会很快丢失数据。建议实例化 RequestCache 的答案太混乱了,而且我永远找不到完整的示例。
但是 ImageDownloader.java 可以工作对我来说太棒了。它使用 HashMap 直到达到容量或直到发生清除超时,然后将内容转移到 SoftReference,从而利用两全其美。
I had been wrestling with this for some time; the answers using SoftReferences would lose their data too quickly. The answers that suggest instantiating a RequestCache were too messy, plus I could never find a full example.
But ImageDownloader.java works wonderfully for me. It uses a HashMap until the capacity is reached or until the purge timeout occurs, then things get moved to a SoftReference, thereby using the best of both worlds.
更好
我建议 IGNITION 这甚至比 Droid fu https://github.com/kaeppler/ 点火
https://github.com/kaeppler/ignition/wiki/Sample-applications
I suggest IGNITION this is even better than Droid fu
https://github.com/kaeppler/ignition
https://github.com/kaeppler/ignition/wiki/Sample-applications
甚至稍后回答,但我编写了一个 Android 图像管理器,它透明地处理缓存(内存和磁盘)。代码位于 Github https://github.com/felipecsl/Android-ImageManager
Even later answer, but I wrote an Android Image Manager that handles caching transparently (memory and disk). The code is on Github https://github.com/felipecsl/Android-ImageManager
迟到的答案,但我想我应该添加一个链接到我的网站,因为我已经写了一个教程如何为 android 制作图像缓存:
http://squarewolf.nl/2010/11/android-image-cache/更新: 该页面有已被下线作为来源已经过时了。我和 @elenasys 一起建议使用 Ignition。因此,对于所有偶然发现这个问题但尚未找到解决方案的人:希望您喜欢! =D
Late answer, but I figured I should add a link to my site because I have written a tutorial how to make an image cache for android:
http://squarewolf.nl/2010/11/android-image-cache/Update: the page has been taken offline as the source was outdated. I join @elenasys in her advice to use Ignition.So to all the people who stumble upon this question and haven't found a solution: hope you enjoy! =D
迟到的答案,但我认为这个库对缓存图像有很大帮助:
https://github.com/crypticminds/ColdStorage。
只需用以下方式注释 ImageView
@LoadCache(R.id.id_of_my_image_view, "URL_to_downlaod_image_from) 它将负责下载图像并将其加载到图像视图中。您还可以指定占位符图像并加载动画。
注释的详细文档位于此处:-
https://github.com/crypticminds/ColdStorage/wiki/@LoadImage-annotation< /a>
Late answer but I think this library will help a lot with caching images :
https://github.com/crypticminds/ColdStorage.
Simply annotate the ImageView with
@LoadCache(R.id.id_of_my_image_view, "URL_to_downlaod_image_from) and it will take care of downloading the image and loading it into the image view. You can also specify a placeholder image and loading animation.
Detailed documentation of the annotation is present here :-
https://github.com/crypticminds/ColdStorage/wiki/@LoadImage-annotation
现在重点是:使用系统缓存。
提供内存和闪存缓存,与浏览器共享。
grr。我希望有人在我编写自己的缓存管理器之前告诉我这一点。
And now the punchline: use the system cache.
Provides both memory and flash-rom cache, shared with the browser.
grr. I wish somebody had told ME that before i wrote my own cache manager.
关于上面优雅的
connection.setUseCaches
解决方案:遗憾的是,如果不做一些额外的努力,它就无法工作。您需要使用ResponseCache.setDefault
安装ResponseCache
。否则,HttpURLConnection
将默默地忽略setUseCaches(true)
位。有关详细信息,请参阅
FileResponseCache.java
顶部的注释:http://libs-for-android.googlecode.com/svn/reference/com/google/android/filecache/FileResponseCache.html
(我会发布这个在评论中,但我显然没有足够的SO业力。)
Regarding the elegant
connection.setUseCaches
solution above: sadly, it won't work without some additional effort. You will need to install aResponseCache
usingResponseCache.setDefault
. Otherwise,HttpURLConnection
will silently ignore thesetUseCaches(true)
bit.See the comments at the top of
FileResponseCache.java
for details:http://libs-for-android.googlecode.com/svn/reference/com/google/android/filecache/FileResponseCache.html
(I'd post this in a comment, but I apparently don't have enough SO karma.)
将它们转换为位图,然后将它们存储在集合(HashMap、列表等)中,或者您可以将它们写入 SD 卡上。
当使用第一种方法将它们存储在应用程序空间中时,您可能希望将它们包装在 java.lang.ref.SoftReference 中,特别是如果它们的数量很大(以便在危机期间对它们进行垃圾收集)。不过,这可能会导致重新加载。
将它们写入 SD 卡上不需要重新加载;只是一个用户权限。
Convert them into Bitmaps and then either store them in a Collection(HashMap,List etc.) or you can write them on the SDcard.
When storing them in application space using the first approach, you might want to wrap them around a java.lang.ref.SoftReference specifically if their numbers is large (so that they are garbage collected during crisis). This could ensue a Reload though.
writing them on SDcard will not require a Reload; just a user-permission.
使用
LruCache
高效缓存图像。您可以从 Android 开发者网站阅读有关LruCache
的信息我在android中使用了下面的图像下载和缓存解决方案。您可以按照以下步骤操作:
第 1 步:
将类命名为
ImagesCache
。我已经为此类使用了Singleton 对象
第 2 步:
创建另一个名为 DownloadImageTask 的类,如果位图在缓存中不可用,则使用该类,它将从此处下载:
第3步:从
Activity
或Adapter
使用注意:如果您想从
Activity的url加载图像类。使用
DownloadImageTask
的第二个构造函数,但如果您想从Adapter
显示图像,请使用DownloadImageTask
的第一个构造函数(例如,您有一个图像ListView
并且您正在设置“适配器”中的图像)活动中的使用情况:
适配器中的使用情况:
注意:
cache.initializeCache()
您可以在应用程序的第一个 Activity 中使用此语句。初始化缓存后,如果您使用ImagesCache
实例,则无需每次都初始化它。我从来不擅长解释事情,但希望这能帮助初学者了解如何使用
LruCache
进行缓存及其用法:)编辑:
现在有一些非常著名的库例如
Picasso
和Glide
可用于在 Android 应用程序中非常有效地加载图像。尝试这个非常简单且有用的库 Picasso for android 和 Android 版 Glide。您无需担心缓存图像。您还可以访问博客了解Glide 和 Picasso 之间的区别
Use
LruCache
to cache images efficiently. You can read aboutLruCache
from Android Developer siteI've used below solution for Images download and caching in android. You can follow steps below:
STEP 1:
make Class Named
ImagesCache
. I've usedSingleton object for this class
STEP 2:
make another class named DownloadImageTask which is used if bitmap is not available in cache it will download it from here:
STEP 3: Usage from your
Activity
orAdapter
Note: If you want to load image from url from
Activity
Class. Use the second Constructor ofDownloadImageTask
, but if you want to display image fromAdapter
use first Constructor ofDownloadImageTask
(for example you have a image inListView
and you are setting image from 'Adapter')USAGE FROM ACTIVITY:
USAGE FROM ADAPTER:
Note:
cache.initializeCache()
you can use this statement in the very first Activity of your application. Once you've initialized the cache you would never need to initialized it every time if you are usingImagesCache
instance.I am never good at explaining things but hope this will help the beginners that how to cache using
LruCache
and its usage :)EDIT:
Now a days there are very famous libraries known as
Picasso
andGlide
which can be used to load images very efficiently in android app. Try this very simple and usefull library Picasso for android and Glide For Android. You do not need to worry about cache images.You can also visit blog for difference between Glide and Picasso
要下载图像并将其保存到存储卡,您可以这样做。
不要忘记将互联网权限添加到您的清单中:
To download an image and save to the memory card you can do it like this.
Don't forget to add the Internet permission to your manifest:
我会考虑使用 droidfu 的图像缓存。它实现了内存中和基于磁盘的图像缓存。您还可以获得一个利用 ImageCache 库的 WebImageView。
以下是 droidfu 和 WebImageView 的完整描述:
http://brainflush.wordpress .com/2009/11/23/droid-fu-part-2-webimageview-and-webgalleryadapter/
I would consider using droidfu's image cache. It implements both an in-memory and disk-based image cache. You also get a WebImageView that takes advantage of the ImageCache library.
Here is the full description of droidfu and WebImageView:
http://brainflush.wordpress.com/2009/11/23/droid-fu-part-2-webimageview-and-webgalleryadapter/