2012-01-05 54 views
1

我有一個從Web服務中拉下數據並將其顯示在ListView中的片段。我有10個不同的選擇器可以用於行背景。循環後重復背景。Android ListView行背景導致OutOfMemory問題

我面臨的問題是設備(Galaxy Nexus!)無法處理顯示所有這些背景。當我通過setbackgroundResource設置背景時,操作系統不斷地調用GC來釋放內存,這使得ListView滾動非常不連貫。

所以我試圖緩存使用的Drawables。我看到了一個改進,但設備最終會拋出一個OutOfMemory異常,因爲有多少Drawable被緩存。舉個例子說明有多少緩存,我需要每個包含兩個drawable的所有10個選擇器,再加上第一個和最後一個,因爲它們是不同的。這是24內存中的drawables。

現在,我想這可能是我正在使用的圖像的大小,我需要縮小它們並按比例拉伸,但我不知道這是否可行。

有什麼建議嗎?我已經花了幾天的時間在這個不停歇的工作上,還沒有找到一個可行的/關閉的解決方案。

感謝

亞當

回答

6

Mimminito,

問題你所描述的瘟疫在Android平臺上衆多開發商。原因在於,當Google實施View Drawables時,他們必須假設前一個Drawable可能需要保留。這是因爲越來越多的平臺上越來越多的應用程序需要這種行爲。

最終,有幾種方法可以緩解這些問題,但沒有人能夠解決所有問題。

  1. 當您替換背景時,獲取原始背景。如果它是一個位圖,recycle()它。如果它是可繪製的,請將參考設置爲空,並通過setCallback刪除其回調(當您更改方向或切換活動時,這尤其重要)。

  2. 圖形是最耗費內存的資源之一。如果您使用Drawable或Bitmap,則每像素使用4個字節。但是如果圖像必須調整大小才能正確顯示,那麼實際上應用程序是否會增大或縮小應用程序。以高分辨率創建圖形非常棒,但對於移動設備,您希望將其縮放到實際將要使用的尺寸。

  3. 如果您使用的圖形很多,您可能會考慮只使用那些可見的圖形。也就是說,如果你有32個項目,但只有3個是可見的,只加載3個可見的,也許是一些直接的鄰居。延遲加載可以用於許多標準化控件。

  4. 我推薦查看.9.png文件。這對於優化圖形非常有用。

  5. 如果您的按鈕有文本,請不要在圖形文件上繪製它。允許Android將文本放置在圖形文件上。其處理方式差異很大,內存消耗大大降低。儘管它可能不夠美觀,但它會增加可靠性(這就是爲什麼你在這裏)

  6. 在某些情況下,可能希望圖形是平坦的位圖,而不是壓縮格式。這減少了處理器和內存的負載,但是以文件大小爲代價。這是因爲壓縮格式必須在內存中進行解壓縮才能使用,但是直到文件實際關閉時纔會釋放內存。 (這甚至不包括用於解壓縮它的運行時代碼的內存,並且當應用程序必須調整圖形尺寸時甚至更昂貴)。

  7. 加入一些額外的System.gc()語句可以幫助緩解負載,但它不可靠,因爲它只告訴系統在其最早的便利情況下它已準備好進行垃圾回收。

  8. 最後,您可以根據設備的分辨率設置多種尺寸。這是您可以通過您的應用程序傳輸的信息。這是我們必須在本地應用程序中執行多種設備支持的方式。

所有這些建議可能會有幫助,但它的信息很多。希望我給了你足夠的實施解決方案,以滿足你的需求。

希望這有助於 FuzzicalLogic

+0

感謝您的答覆。事實上,它提供了大量的信息,其中一些可能有所幫助。我的第一個想法是調整圖像的大小,以便它們按照密度縮放,因爲我使用的原稿非常大。我會看到這是如何幫助的,接下來我將更有可能爲他們修補九個。最大的問題是,當允許系統處理它所有的itseld(通過在getView()中設置背景資源),ListView在快速滾動時變得太過分了,因爲它試圖一次加載很多drawable。 – Mimminito 2012-01-05 14:36:51

0

也許您在cacheColorHint設置爲透明(如果你有一個固定的背景圖像):android:cacheColorHint="#00000000"。對我來說,它也多次呼籲GC。

我發現,設置以下屬性禁用android的列表視圖緩存和列表滾動平滑(GC未叫,往往更多):

android:scrollingCache="false" 
android:animationCache="false" 

而且如果u想擺脫默認的選擇顏色使用此:

android:listSelector="#00000000"