2013-03-17 12 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"); 

Witam, oto kod. Dostaję bitmapę z adresu URL z powodzeniem (Log mówi, że mapa bitowa nie jest pusta i mogę ją łatwo wyświetlić). Następnie próbuję umieścić go w LruCache i odzyskać, ale zwraca zero. (Log mówi, że newBitmap ma wartość null). Gdzie jest mój błąd? Powiedz mi, Proszę. Android 4.1.2 Rozmiar pamięci podręcznej 8192 Kb.LruCache nie działa

+0

Czy próbowałeś, aby obliczenia rozmiaru pamięci podręcznej były prawidłowe? I co znaczy "sizeOf()"? Czy na pewno obraz znajduje się naprawdę w pamięci podręcznej? – ConcurrentHashMap

+0

http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html. – Raghunandan

+0

Och, ten obraz był 9000 kb, myślałem, że jego 1.19 mb jako plik. Problem rozwiązany. Dziękuję Ci. Plaese, powiedz mi, dlaczego plik 1.19 mb zwraca 9000 kb w getByteCount/1024? – Faceles

Odpowiedz

8

Jeśli jest 1,19 MB na dysku, ale ~ 9 MB w pamięci, oznacza to, że jako skompresowany plik JPEG ma 1,19 MB, a po wyodrębnieniu go do mapy bitowej (nieskompresowanej), którą można wyświetlić, zajmie 9 MB w pamięci. Jeśli jest to obraz o wymiarach 1920 x 1200 pikseli sugerowany przez adres URL w fragmencie kodu, obraz będzie zajmował 1920 x 1200 x 4 bajty pamięci (4 bajty dla każdego piksela reprezentujące wartości ARGB od 0 do 256 razy 2,3 miliona wszystkich pikseli = 9 216 000 bajtów). Jeśli używasz 1/8 dostępnej pamięci dla tej pamięci podręcznej, możliwe/prawdopodobne jest, że 9 MB przekroczy to całkowite miejsce w pamięci, aby Bitmap nigdy nie trafił do pamięci podręcznej lub został natychmiast wyeksmitowany.

Prawdopodobnie będziesz chciał obniżyć obraz w czasie dekodowania, jeśli jest on tak duży (używając BitmapFactory.Options.inSampleSize ... dużo dokumentacji w Internecie, aby go użyć, jeśli jeszcze nie jesteś zaznajomiony).

Ponadto używasz Runtime.maxMemory do obliczania rozmiaru pamięci podręcznej. Oznacza to, że żądasz maksymalnej ilości pamięci, którą może wykorzystać cała maszyna wirtualna.

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

Bardziej powszechnym rozwiązaniem jest stosowanie wartość zwrócona do Ciebie przez ActivityManager.getMemoryClass metoda().

Oto przykładowy fragment kodu i definicja metody w dokumentach dla odniesienia.

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

Gdybym był komentatorem piłkarskim: Rich Strikes ponownie, solidny cel, Dalvik nie ma szans na powstrzymanie tego Kodeksu, co za wspaniały wieczór! –

0

Można również recykling bitmap, że wyskoczy z lrucache

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

Android przykładem było źle, gdy dzieląc Runtime Maxmemory przez 1024 w następujący wiersz:

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

Jednostką maxMemory jest bajt, który jest taki sam jak "c acheSize '('/8 'oznacza, że ​​użyje ósmej dostępnej pamięci bieżącej aktywności). Dlatego "/ 1024" sprawi, że "cacheSize" będzie bardzo mały, tak że żadna bitmapa nie może być faktycznie "buforowana" w "mMemoryCache".

Rozwiązaniem będzie usunięcie "/ 1024" w powyższym kodzie.