2013-03-17 26 views
7
final int maxMemory = (int) (Runtime.getRuntime().maxMemory()/1024); 
    final int cacheSize = maxMemory/8; 
    mMemoryCache = new LruCache<String, Bitmap>(cacheSize) { 
      @Override 
      protected int sizeOf(String key, Bitmap bitmap) { 
       // The cache size will be measured in kilobytes rather than 
       // number of items. 
       return bitmap.getByteCount()/1024; 
      } 
     }; 
    URL url = new URL("http://s2.goodfon.ru/image/260463-1920x1200.jpg"); 
    Bitmap bitmap = BitmapFactory.decodeStream((InputStream) url.getContent(), null, options); 
    if(bitmap != null) 
     Log.i("Success", "BITMAP IS NOT NULL"); 

    String key = "myKey"; 
    Log.i("Get is null", "putting myKey"); 
    mMemoryCache.put(key, bitmap); 

    Bitmap newBitmap = mMemoryCache.get(key); 
    if(newBitmap == null) 
     Log.i("newBitmap", "is null"); 

你好,這裏是一個代碼。我成功地從URL獲取位圖(日誌說,位圖不是空的,我可以很容易地顯示它)。然後我試圖將它放入LruCache中並將其取回,但它返回null。 (日誌說newBitmap爲空)。我的錯誤在哪裏?請告訴我。 Android 4.1.2緩存大小8192 Kb。LruCache不工作

+0

那麼,你有沒有試過,你的緩存大小的計算是正確的?那麼'sizeOf()'輸出的是什麼?你確定圖片真的在緩存裏嗎? – ConcurrentHashMap 2013-03-17 10:46:41

+0

http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html。 – Raghunandan 2013-03-17 10:56:56

+0

哦,那個圖像是9000 kb,我認爲它的文件是1.19 MB。問題解決了。謝謝。 Plaese告訴我,爲什麼1.19 MB文件在getByteCount/1024中返回9000 kb? – Faceles 2013-03-17 11:06:46

回答

8

如果它在磁盤上是1.19 MB,但是在內存中是9 MB,這意味着作爲一個壓縮的JPEG文件,它是1.19 MB,一旦將它解壓縮到可以顯示的位圖(未壓縮)中,它將佔用內存9 MB。如果它是代碼片段中的url所建議的1920 x 1200像素圖像,則圖像將佔用1920 x 1200 x 4個字節的內存(每個像素4個字節代表0到256的ARGB值,總共230萬像素= 9,216,000字節)。如果您將1/8的可用內存用於此緩存,可能/可能9MB超過了總內存空間,因此Bitmap永遠不會將其放入緩存或立即驅逐。

你可能會想要在解碼時下載圖像,如果它很大(使用BitmapFactory.Options.inSampleSize ...很多網絡上的文檔,如果你不熟悉的話)。

此外,您正在使用Runtime.maxMemory來計算您的緩存大小。這意味着您要求允許整個VM允許使用的最大內存量。

http://developer.android.com/reference/java/lang/Runtime.html#maxMemory%28%29

比較常見的方法是使用由ActivityManager.getMemoryClass()方法還給你的價值。

下面是示例代碼片段和文檔中的方法定義以供參考。

ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); 
    int memClassBytes = am.getMemoryClass() * 1024 * 1024; 
    int cacheSize = memClassBytes/8; 
    mMemoryCache = new LruCache<String, Bitmap>(cacheSize) 

http://developer.android.com/reference/android/app/ActivityManager.html#getMemoryClass%28%29

+0

如果我是足球評論員:Rich Strikes再一次,堅實的進球,Dalvik沒有機會停止這個守則,這個美麗的夜晚是多麼的美好! – 2013-07-06 10:45:38

0

您還可以回收,從lrucache

final Bitmap bmp = mLruCache.put(key, data); 
if (bmp != null) 
    bmp.recycle(); 
0

在下面一行將運行maxMemory當1024 Android的例子是錯誤的彈出位圖:

final int maxMemory = (int) (Runtime.getRuntime().maxMemory()/1024); 

maxMemory的單位是Byte,與'c acheSize'('/ 8'意味着它將使用當前活動的可用內存的八分之一)。因此,'/ 1024'會使'cacheSize'非常小,使得'mMemoryCache'中實際上沒有位圖可以'緩存'。

解決方法將在上面的代碼中刪除'/ 1024'。