2012-02-16 133 views
7

我有一塊圖像要加載到我的屏幕上。所有圖像都是我下載並存儲在SD-CARD上的文件。安卓快速位圖加載

到目前爲止,我發現了兩種方式來做到這一點,首先是加載它們在主線程,當活動開始,(我有大約70圖像和我花約2.1秒加載它們全部)。

另一種方式是我現在正在測試的東西。將它們加載到分離的線程上,同時我可以向用戶顯示加載動畫。現在我的執行ThreadPoolExecutor花了4.3秒。我在10個線程上完成了它。

而最後的方法,(那就是我還不測試的唯一的事)正在與精靈表。

我不能使用應用程序緩存,因爲在我的應用程序中,我有很多屏幕,每個屏幕都有自己的圖像集。

你怎麼想,什麼是加載大量圖像的最快方法?你知道什麼加速工藝,可以幫助我嗎?

+0

你還沒有提到你的圖像的大小,如果你能減少它們的大小,當你加載它們(如取一個500萬像素的JPEG並將其作爲320x240縮略圖加載)。如果你允許這樣做,它可以大大加速圖像的加載。 – BitBank 2012-02-25 00:05:50

回答

2

一種選擇是使用使用WeakReference創建圖像緩存,以便系統遇到內存不足情況時將圖像從內存中移除。這樣,您可以將圖像保存在內存中,並且只需在SD卡不在內存中時加載即可。所以你當前的活動將始終保持對所需位圖的硬引用,並且圖像緩存將保留對位圖的弱引用。

以下是關於弱引用一些信息:

JavaDoc weakReference

StackOverflow post discussing using weak reference for cache

+1

-1:這種方法在所有sdk9以上的設備上沒有任何用處,因爲垃圾回收器非常具有侵略性,它幾乎可以清除所有弱引用,當前推薦的方法是LRU Cache(請參閱http://developer.android.com/training /displaying-bitmaps/cache-bitmap.html) – for3st 2014-04-08 10:51:14

8
  1. 請勿在主線程中加載。如果您阻止主線程,延遲2.1秒會導致ANR(應用程序無響應)錯誤導致死亡。

  2. 加載在單獨的線程中。不要創建10個線程,而是創建一個AsyncTask,並在doInBackground中逐個加載所有圖像。

    在AsyncTask中加載應該(幾乎)與在主線程中加載相同的時間。不要放太多花哨的動畫,這樣主線程不會消耗太多的CPU時間。

0

這樣做的一種方法是實現一種監聽器/觀察者。

從你的UI線程,啓動其他線程,將加載圖像。一旦圖像被加載,線程將調用activity類中實現的回調方法來更新相應的圖像視圖。

而不是android異步任務,我會去我的線程(池/執行程序)。我將在加載它們之前獲取所有可能的圖像路徑,並將它們分派給線程加載圖像。在回調中,我知道在哪裏更新圖像。

另外,你也可以檢查加載程序如何執行你的情況。

0

顯然,你不應該在UI線程中留下2s長的操作。

我假設的ThreadPoolExecutor是二年即可回收解決方案,但它不是最佳的在池中創建多個線程。在後臺線程就足夠了。我敢打賭,只要改變這一點,你的表現就會更好。

我不直接從活動推薦的AsyncTask,因爲it is fragile to config change

我不建議使用精靈。在內存有限的移動設備上增加一張圖像的尺寸是非常危險的。特別是精靈,你必須得到部分Bitmap,因此在內存中有完整的位圖一會兒。

現在我明白了您的具體問題,我想你會通過Lazy loading of images in a listview,因爲問題非常相似。