2014-09-02 19 views
1

在我的應用程序中的幾個Activity顯示ListView中的圖像,其中ListView的每一行都包含ImageView對許多本地LruCaches執行全局LruCache

這個例子是一個搜索屏幕,用戶搜索,獲取結果,並顯示每個結果的圖片。

我試圖衡量實施全球LruCache的成本/收益與每個Activity包含其本地LruCache

這是我的兩個主要問題。兩者都圍繞着這樣的事實:我的應用程序非常大,這意味着有相當多的屏幕顯示這些圖像。此外,我的應用程序有流行的側面菜單的導航方式。因此,我可以打開菜單,點擊Activity B,打開菜單,點擊Activity A,打開菜單等等,然後無限期創建一個ABABABABABABABABAB的Activity堆棧。

全球

不會Activity s的使用Bitmap期從全球LruCacheImageView小號包含這些Bitmaps引用?假設用戶通過點擊Button導航離開ActivityActivity現在在Activity堆棧上,並且仍然保留對這些Bitmaps的引用。如果LruCache彈出一個Bitmap關閉,當ImageView在堆棧上的某些Activity持有對它的引用時,那麼Bitmap是否真的可以回收?

我以前創建了自己的自定義緩存。如果我在Bitmap上調用recycle(),然後用戶點擊返回按鈕返回包含設置爲BitmapImageView的堆棧上的某個Activity,則該應用程序將崩潰。這就是爲什麼我相信ImageView s在Activity的堆棧上仍然持有對Bitmap s的引用。

本地

正如我前面提到的。我的應用程序非常大,導航的側面菜單風格允許用戶創建相當大的堆棧。這將創建很多LruCache s。而且,由於您在初始化時必須聲明LruCache的大小,因此似乎沒有任何選擇大小的好方法。

想法?建議?

在這一點上,我認爲我必須做全球,但我不知道如何解決堆棧引用問題Activity。我無法想象這不是許多應用程序沒有遇到的問題。我不知道爲什麼我沒有找到有關它的信息。

回答

3

我試圖衡量實施全球 LruCache vs每個活動包含自己的本地LruCache的成本/收益。

全局LruCache是​​前進的方式,因爲在不同的活動實例中可能會引用同一組位圖。 LruCache可以被定義爲Application的一部分。如果活動堆棧可以託管同一活動的多個實例(如ABABABAB ..),那麼在該活動中本地創建LruCache將是一個壞主意。由於每個活動實例中的LruCache都會保留Dalvik VM中定義的內存量,因此很快就會出現內存不足的情況。假設應用程序內存爲32Mb,並且您決定LruCache大小爲4Mb,即1/8。現在,當我們創建活動A的近7個實例時,內存消耗將達到7 * 4 = 28Mb,這本身可能會觸發OOM。

使用來自全局LruCache 的位圖的ImageViews不會活動包含對這些位圖的引用嗎?

是的ImageView也將有一個強烈的位圖參考。如果引用保留在LruCache中,那麼引用計數在那一刻將爲2。

如果LruCache彈出一個位圖了,可以說真正的位圖被回收 當在堆棧上的一些活動的ImageView的持有參考 呢?

不能回收位圖內存,因爲仍然有些ImageView對它有很強的參考。

在這一點上,我認爲我必須做全球性的,但我不知道如何解決 活動堆棧引用問題。

LruCache的主要角色是持有對更頻繁使用的位圖的強烈參考。因此,如果沒有任何ImageView擁有強大的引用,則會阻止位圖被垃圾收集。

另外請記住,對於Android 2.3.3及更低版本,您需要實現引用計數機制,以便回收位圖。

+0

謝謝你的迴應。是否有解決方案:'不能回收位圖內存,因爲還有一些ImageView對它有強烈的參考意義?這似乎是一個問題。也許,在onPause()中,將所有ImageView指向其他圖像? – Andrew 2014-09-03 13:26:38