发出跨活动访问LRU磁盘缓存的问题

时间:2013-01-14 16:57:43

标签: android android-listview android-image

我正在使用Jake Wharton's LRU disk cache来存储和检索ListView中显示的位图。只要我在同一个活动中存储和访问位图,这样就可以正常工作。但是,如果我尝试从应用程序中的其他活动访问缓存(即所以我不必将同一图像下载两次),我会得到一个NullPointerException。我在这里错过了什么吗?这不是可以/将要删除文件的内存缓存。不应该从应用程序中的所有活动访问磁盘缓存,只要我将它们指向内部存储中的正确目录即可?

01-14 22:53:44.465: E/AndroidRuntime(10720): java.lang.NullPointerException
01-14 22:53:44.465: E/AndroidRuntime(10720): at java.util.regex.Matcher.reset(Matcher.java:181)
01-14 22:53:44.465: E/AndroidRuntime(10720): at java.util.regex.Matcher.<init>(Matcher.java:94)
01-14 22:53:44.465: E/AndroidRuntime(10720): at java.util.regex.Pattern.matcher(Pattern.java:290)
01-14 22:53:44.465: E/AndroidRuntime(10720): at com.example.echofriendly.DiskLruCache.validateKey(DiskLruCache.java:629)
01-14 22:53:44.465: E/AndroidRuntime(10720): at com.example.echofriendly.DiskLruCache.get(DiskLruCache.java:375)
01-14 22:53:44.465: E/AndroidRuntime(10720): at com.example.echofriendly.DiskLruImageCache.containsKey(DiskLruImageCache.java:145)
01-14 22:53:44.465: E/AndroidRuntime(10720): at com.example.echofriendly.ChatroomFragment.getMessages(ChatroomFragment.java:309)
01-14 22:53:44.465: E/AndroidRuntime(10720): at com.example.echofriendly.ChatroomFragment.access$3(ChatroomFragment.java:284)
01-14 22:53:44.465: E/AndroidRuntime(10720): at com.example.echofriendly.ChatroomFragment$2.run(ChatroomFragment.java:94)
01-14 22:53:44.465: E/AndroidRuntime(10720): at java.lang.Thread.run(Thread.java:1019)

3 个答案:

答案 0 :(得分:1)

  

不应该从应用程序中的所有活动中访问磁盘缓存,只要我将它们指向内部存储中的正确目录即可吗?

听起来好像是在需要它的每个Activity中实例化缓存。我认为这不是一个好主意。由于Jake的LruCache使用日志,在我看来,在同一目录上工作的不同实例很容易分散注意力。

我的建议是,您将某种单例作为活动和缓存之间的层引入,或者仅将引用存储到整个应用程序的一个缓存实例。

此外,我建议你使用某种两级缓存,例如:内存缓存与磁盘缓存相结合(这是我在我的应用程序中所做的)。因此,您可以先检查内存缓存,如果缓存在那里,可以非常快速地获取图像。 (可以是同步的)如果不存在,则询问diskcache。 (应该是异步的)作为最后一次调用,你会下载它。 (也是异步的)

答案 1 :(得分:0)

当活动被清理时,缓存可能会被破坏。检查库中的回调以进行此类清理调用。

答案 2 :(得分:0)

我有同样的问题:使用相同缓存的几个活动。出现两个问题: - 缓存从未被驱逐......我认为原因是第二点 - 如果在活动A之后调用活动B:    - 活动B已启动并打开缓存(但活动A尚未关闭缓存!)    - 活动A在onStop()方法中关闭缓存...而B刚打开它...

我的解决方案是为每个活动提供一个缓存目录:

// retrieve the name of the activity
String nameActivity = ModelActivity.getCurrentActivity().getClass().getSimpleName();

// set the cache directory with a name related to the activity
    DiskLruImageCache imageDiskCache = new DiskLruImageCache(ModelActivity.getCurrentContext(), 
                        "cacheMediaActivity"+nameActivity, 
                        DISK_CACHE_SIZE, 
                        CompressFormat.JPEG, 
                        70);

它对我有用!