Java 使用带有缓存而非缓存的ImageDownloader

Java 使用带有缓存而非缓存的ImageDownloader,java,android,Java,Android,我正在开发一个应用程序,它使用一个动态填充的列表视图,其中每个项目都包含一个需要下载的图像。此外,当单击列表中的任何项目时,它会打开一个详细信息页面,该页面再次显示相同的图像以及其他一些图像 正如我们所知,最好使用异步任务来进行实际下载,最好使用缓存机制来加快图像显示速度,并尽量减少多次下载中的实际数据使用 在搜索了相当长一段时间后,我最终使用了Google示例代码,该代码声称是一种异步和缓存方法来下载图像 我遇到的问题是,调用该类时,该类似乎没有正确缓存图像。这就是 我的自定义类(构建列表视图

我正在开发一个应用程序,它使用一个动态填充的列表视图,其中每个项目都包含一个需要下载的图像。此外,当单击列表中的任何项目时,它会打开一个详细信息页面,该页面再次显示相同的图像以及其他一些图像

正如我们所知,最好使用异步任务来进行实际下载,最好使用缓存机制来加快图像显示速度,并尽量减少多次下载中的实际数据使用

在搜索了相当长一段时间后,我最终使用了Google示例代码,该代码声称是一种异步和缓存方法来下载图像

我遇到的问题是,调用该类时,该类似乎没有正确缓存图像。这就是

我的自定义类(构建列表视图)中调用图像下载的代码部分如下:

ImageDownloader getimage = new ImageDownloader();
getimage.download(logoURL, ivLogo);
ImageDownloader是上面引用的类

图像加载,但很明显,它们每次都是从web加载的。我在ImageDownloader.class中添加了一些日志,以帮助跟踪发生的情况。我发现,第一次请求映像时,它第一次从缓存获取调用失败(如预期),getBitmapFromCache返回null,并调用forceDownload

public void download(String url, ImageView imageView, String cookie) {
    resetPurgeTimer();
    Bitmap bitmap = getBitmapFromCache(url);
    Log.i(LOG_TAG, "Bitmap is: " + bitmap);

    if (bitmap == null) {
        Log.i(LOG_TAG, "Forcing Download");
        forceDownload(url, imageView, cookie);
    } else {
        cancelPotentialDownload(url, imageView);
        imageView.setImageBitmap(bitmap);
    }
}
在执行过程中,类向下移动到将映像/url添加到缓存的位置

private void addBitmapToCache(String url, Bitmap bitmap) {
    Log.i(LOG_TAG, "Incoming Add Cache Info: URL: " + url + " Bitmap: " + bitmap);
    if (bitmap != null) {
        Log.i(LOG_TAG, "Entering the add image to cache section");
        synchronized (sHardBitmapCache) {
            sHardBitmapCache.put(url, bitmap);
            Bitmap returnedbitmap = getBitmapFromCache(url);
            Log.i(LOG_TAG, "Returned bitmap immediately after adding: " + bitmap);
        }
    }
}
我添加了日志来验证是否添加了缓存,然后执行getBitmapFromCache,日志正确显示返回的位图/url哈希返回

Incoming request to get Image, URL: http://www.yourlogoresources.com/wp-content/uploads/2011/11/Wendys-logo.png

Trying Hard Cache with URL: http://www.yourlogoresources.com/wp-content/uploads/2011/11/Wendys-logo.png

Hard Bitmap is: null

Trying Soft Cache with URL: http://www.yourlogoresources.com/wp-content/uploads/2011/11/Wendys-logo.png

Return from initial entry call: null

Entering forced Download

Incoming Add Cache Info: URL:http://www.yourlogoresources.com/wp-content/uploads/2011/11/Wendys-logo.pngBitmap: android.graphics.Bitmap@40762f28

Entering the add image to cache section

Trying Hard Cache withURL: http://www.yourlogoresources.com/wpcontent/uploads/2011/11/Wendys-logo.png

Hard Bitmap is: android.graphics.Bitmap@40762f28

Returned bitmap immediately after adding:android.graphics.Bitmap@40762f28
因此,缓存似乎已正确填充,但是,下一次请求该图像时(即当您滚动listview时),缓存的图像将无法再次找到,并且从入口点下载的getBitmapFromCache(url)返回null

Incoming request to get Image, URL: http://www.yourlogoresources.com/wp-content/uploads/2011/11/Wendys-logo.png

Trying Hard Cache with URL: http://www.yourlogoresources.com/wp-content/uploads/2011/11/Wendys-logo.png

Hard Bitmap is: null

Trying Soft Cache with URL: http://www.yourlogoresources.com/wp-content/uploads/2011/11/Wendys-logo.png

Return from initial entry call: null

Entering forced Download
所以我不知道为什么缓存会被填充,但是当再次检查时,只返回null

编辑

最后,我从我的主要活动中使用了对ImageDownloader的静态引用,如下所示:

public class myActivity extends Activity implements OnClickListener {
     public final static ImageDownloader GetImage = new ImageDownloader();
然后在任何需要图像下载的地方这样打电话:

    myActivity.GetImage.download(logoURL,  ivLogo);

感谢所有的帮助。

查看
ImageDownloader
的代码

它正在使用主缓存
private final HashMap sHardBitmapCache

和一个辅助静态缓存
私有最终静态ConcurrentHashMap sSoftBitmapCache

从主缓存中踢出的条目将放入辅助缓存

现在,每当您想要下载图像时,如果您创建一个新的
ImageDownloader
实例,您实际上没有使用缓存机制,因为每个
ImageDownloader
实例将只包含使用此实例下载的单个图像


PS:问题中的代码看起来好像每次下载都在使用实例。

查看
ImageDownloader
的代码

Incoming request to get Image, URL: http://www.yourlogoresources.com/wp-content/uploads/2011/11/Wendys-logo.png

Trying Hard Cache with URL: http://www.yourlogoresources.com/wp-content/uploads/2011/11/Wendys-logo.png

Hard Bitmap is: null

Trying Soft Cache with URL: http://www.yourlogoresources.com/wp-content/uploads/2011/11/Wendys-logo.png

Return from initial entry call: null

Entering forced Download
它正在使用主缓存
private final HashMap sHardBitmapCache

和一个辅助静态缓存
私有最终静态ConcurrentHashMap sSoftBitmapCache

从主缓存中踢出的条目将放入辅助缓存

现在,每当您想要下载图像时,如果您创建一个新的
ImageDownloader
实例,您实际上没有使用缓存机制,因为每个
ImageDownloader
实例将只包含使用此实例下载的单个图像


PS:您在问题中的代码看起来好像每次下载都使用一个实例。

Vikram,是的,我相信您是正确的,我为每个图像都提供了一个新实例。我想我应该找到一种方法,只支持一个ImageDownloader实例,并在每次下载时简单地使用该实例。为了澄清这一点,我有一个Activity类,它对CustomAdapter类(以数组作为输入)进行初始调用,然后为数组中的每个条目调用ImageDownloader类。作为Java的新手,我只是不确定如何只实例化ImageDownloader的一个实例,而是能够从多个其他类访问它。您可以通过应用程序对象公开ImageDownloader的实例。下面是一个例子:。或者你可以简单地把它变成一个静态对象再次感谢Vikram,我会检查它。我最终在我的主要活动中实现了一个静态对象,实例化ImageDownloader,然后使用该对象引用将来的所有下载。Vikram,是的,我相信你是正确的,我为每个图像都提供了一个新实例。我想我应该找到一种方法,只支持一个ImageDownloader实例,并在每次下载时简单地使用该实例。为了澄清这一点,我有一个Activity类,它对CustomAdapter类(以数组作为输入)进行初始调用,然后为数组中的每个条目调用ImageDownloader类。作为Java的新手,我只是不确定如何只实例化ImageDownloader的一个实例,而是能够从多个其他类访问它。您可以通过应用程序对象公开ImageDownloader的实例。下面是一个例子:。或者你可以简单地把它变成一个静态对象谢谢Vikram,我会检查一下。我最终在我的主要活动中实现了一个静态对象,实例化ImageDownloader,然后使用该对象引用所有未来的下载。
Incoming request to get Image, URL: http://www.yourlogoresources.com/wp-content/uploads/2011/11/Wendys-logo.png

Trying Hard Cache with URL: http://www.yourlogoresources.com/wp-content/uploads/2011/11/Wendys-logo.png

Hard Bitmap is: null

Trying Soft Cache with URL: http://www.yourlogoresources.com/wp-content/uploads/2011/11/Wendys-logo.png

Return from initial entry call: null

Entering forced Download