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

Hallo, hier ist ein Code. Ich bekomme Bitmap von URL erfolgreich (Log sagt Bitmap ist nicht null und ich kann es einfach anzeigen). Dann versuche ich, es in LruCache zu bringen und es zurück zu bekommen, aber es gibt null zurück. (Log sagt, dass newBitmap null ist). Wo ist mein Fehler? Erzähl es mir bitte. Android 4.1.2 Cache-Größe 8192 Kb.LruCache funktioniert nicht

+0

Also, haben Sie versucht, dass Ihre Berechnung für die Cache-Größe korrekt ist? Und was gibt 'sizeOf()' aus? Sind Sie sicher, dass das Bild wirklich im Cache ist? – ConcurrentHashMap

+0

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

+0

Oh, das Bild war 9000 kb, ich dachte seine 1,19 MB als Datei. Problem gelöst. Vielen Dank. Bitte sagen Sie mir, warum 1,19 MB Datei 9000 KB in getByteCount/1024 zurückgibt? – Faceles

Antwort

8

Wenn es 1,19 MB auf der Festplatte, aber ~ 9 MB im Speicher ist, bedeutet das, dass es als komprimierte JPEG-Datei 1,19 MB ist und sobald Sie es in eine Bitmap (unkomprimiert) extrahieren, die angezeigt werden kann 9 MB im Speicher. Wenn es sich um ein 1920 x 1200 Pixel Bild handelt, wie es die URL in Ihrem Code-Snippet vorschlägt, wird das Bild 1920 x 1200 x 4 Bytes Speicher aufnehmen (4 Bytes für jedes Pixel, um ARGB Werte von 0 bis 256 mal 2,3 Millionen Gesamtpixel darzustellen) = 9,216,000 Bytes). Wenn Sie 1/8 Ihres verfügbaren Speichers für diesen Cache verwenden, ist es möglich/wahrscheinlich, dass 9 MB den gesamten Speicherplatz überschreiten, so dass die Bitmap niemals in den Cache gelangt oder sofort gelöscht wird.

Wahrscheinlich werden Sie das Bild zur Dekodierzeit herunterskalieren wollen, wenn es so groß ist (unter Verwendung von BitmapFactory.Options.inSampleSize ... viel Dokumentation im Internet für die Verwendung, wenn Sie nicht bereits vertraut sind).

Außerdem verwenden Sie Runtime.maxMemory, um Ihre Cache-Größe zu berechnen. Das bedeutet, dass Sie die maximale Speichermenge anfordern, die die gesamte VM verwenden darf.

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

Der häufigere Ansatz ist die Verwendung der Wert wieder zu Ihnen durch den ActivityManager.getMemoryClass() -Methode angegeben.

Hier finden Sie ein Beispielcode-Snippet und die Methodendefinition in den Dokumenten als Referenz.

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

Wenn ich ein Football Commentator wäre: Rich Strikes wieder, solides Goal, Dalvik hat keine Chance, diesen Code zu stoppen, was für ein schöner Abend! –

0

Sie können auch Bitmaps recyceln, die LRUCache von herausspringt

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

Das Android Beispiel nicht in Ordnung war, wenn sie von 1024 in der folgenden Zeile Runtime MaxMemory Dividieren:

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

Die Einheit des maxMemory ist Byte, das ist das gleiche mit dem 'c acheSize '('/8 'bedeutet nur, dass es den achten verfügbaren Speicher der aktuellen Aktivität verwendet). Daher wird '/ 1024' die 'cacheSize' extrem klein machen, so dass keine Bitmap tatsächlich in 'mMemoryCache' zwischengespeichert werden kann.

Die Lösung wird '/ 1024' im obigen Code löschen.