2013-01-14 55 views
1

我使用Jake Wharton's LRU disk cache存儲和retrive被顯示在ListView位圖。只要存儲並訪問同一活動中的位圖,此工作正常。但是,如果我嘗試從應用程序中的其他活動訪問緩存(即,所以我不必下載相同的圖像兩次),我得到一個NullPointerException。我在這裏錯過了什麼嗎?這不是內存緩存,文件可能會被刪除。不應該從應用程序中的所有活動中訪問磁盤緩存,只要我將它們指向內部存儲中的正確目錄即可?問題訪問LRU磁盤緩存翻過activites

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) 
+0

似乎它應該工作。你可以發佈NPE的堆棧跟蹤嗎? – kabuko

+0

我將張貼堆棧跟蹤,當我下班回家 – Rarw

回答

1

只要我將它們指向內部存儲器中的正確目錄,磁盤緩存是否可以從應用程序中的所有活動訪問?

聽起來就像你正在實例化你需要它的每個Activity中的緩存。我不認爲這是一個好主意。由於Jake的LruCache使用日誌,所以在我看來,在同一個目錄下工作的不同實例可以輕鬆分散彼此的注意力。

我的建議是你介紹某種單身的無論是作爲活動和高速緩存或將只存儲引用爲整個應用程序只有一個緩存實例之間的層。

此外,我會建議你使用某種二級緩存,例如一個memcache結合一個磁盤緩存(這是我在我的應用程序中做的)。所以你可以先檢查一下memcache,如果它被緩存在那裏,那麼圖像真的很快。 (可以是同步的)如果它不在那裏,你問磁盤緩存。 (應該是異步的)並且最後一次調用您可以下載它。 (也異步)

+0

你的權利,我正在實例化每個活動中的緩存,因爲我需要它。當您從不同的活動中讀/寫SharedPreferences時,我幾乎像處理SharedPreferences一樣。如何建議使用緩存的單個引用? – Rarw

+0

引入一個自定義'Application'類,將緩存存儲爲'public static DiskLruCache diskCache'。該字段可以直接在那裏實例化。或者,如果您想更多地控制參數,請使用您的第一個活動,並在存儲的實例爲null時使用'new'實例化緩存。當需要緩存時,每個Activity都可以使用'MyApplication.diskCache'。 – deekay

+0

使用StackTrace進行編輯之後,它看起來像使用'null'作爲鍵。 – deekay

0

當活動清理完畢後,緩存可能會被破壞。檢查庫中的回調以獲取此類清理調用。

+0

豈不緩存持續到活性被停止或終止?也許我不瞭解應用程序生命週期如何處理緩存 – Rarw

+0

如果您在Application類中設置緩存,那麼它將永遠不會被銷燬,直到應用程序關閉。如果您的活動中有一項是活動,那麼您可以保證Application類永遠是「活着的」。 – slott

0

我有同樣的問題:使用相同的緩存幾項活動。出現兩個問題: - 緩存從未被驅逐......我想原因是第二點 - 如果活動B在活動A之後叫: - b活動發起並打開緩存(但活動一不關閉緩存還) - 活性的中的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); 

它適用於我!