2013-07-15 21 views
6

Sto tentando di visualizzare un listview con molte (remote) immagini. Sto cercando di usare la pallavolo per il compito.Memorizzazione nella cache di volley e bitmap

Volley funziona in qualche modo, ma non abbastanza. In ImageLoader.get volley ha il seguente pezzo di codice:

final String cacheKey = getCacheKey(requestUrl, maxWidth, maxHeight); 

    // Try to look up the request in the cache of remote images. 
    Bitmap cachedBitmap = mCache.getBitmap(cacheKey); 
    if (cachedBitmap != null) { 
     // Return the cached bitmap. 
     ImageContainer container = new ImageContainer(cachedBitmap, requestUrl, null, null); 
     imageListener.onResponse(container, true); 
     return container; 
    } 

Tuttavia, getCacheKey produce una chiave simile:

/** 
* Creates a cache key for use with the L1 cache. 
* @param url The URL of the request. 
* @param maxWidth The max-width of the output. 
* @param maxHeight The max-height of the output. 
*/ 
private static String getCacheKey(String url, int maxWidth, int maxHeight) { 
    return new StringBuilder(url.length() + 12).append("#W").append(maxWidth) 
      .append("#H").append(maxHeight).append(url).toString(); 
} 

cioè che aggiunge qualche "metadati" come larghezza e l'altezza alla chiave.

Questa chiave mai produce un hit e se l'immagine non è nella cache L1 viene recuperata online. Quando l'immagine viene recuperata online, viene salvata nella cache del disco ma Volley la salva con l'URL (e solo l'URL) come chiave.

È questo comportamento previsto? Mi sto perdendo qualcosa?

+0

potrebbe dipendere dalle intestazioni dalla risposta – njzk2

+1

hai capito perché la scarica non produce un successo? – iamrelos

+0

È possibile utilizzare [droidQuery] (http://bit.ly/droidquery) per completare le richieste restanti asincrone (Ajax) e controllare la cache più facilmente (indipendentemente dal fatto che sia e per quanto tempo conservare un oggetto memorizzato nella cache). – Phil

risposta

-1

Questo è esattamente il modo in cui si desidera che funzioni.

  1. Colpire l'url e ottenere l'immagine quando non è disponibile.
  2. Carica l'immagine dalla cache, se disponibile.
+0

Questo non ha senso. Prima di tutto vuoi caricare l'immagine dalla cache prima di premere l'url. In secondo luogo, questo non risponde alla mia domanda su come funziona volley – Markus

+0

Ho capito la tua domanda come se funzionasse come hai detto nel commento sopra. –

+0

Non capisco cosa stai dicendo. Ho chiesto "perché la cache interna del volley non produce mai un successo" – Markus

1

Puoi pubblicare la tua classe che implementa ImageCache.

L'ho appena visto e ho capito nel mio codice che non aggiungevo la bitmap alla memoria quando la caricava dal disco, quindi la ricaricherò sempre dal disco ogni volta.

Questo è un semplice esempio di quello che voglio dire e dove stavo andando male

@Override 
    public Bitmap getBitmap(String cachKey) { 

     Bitmap b = null; 

      //check the memory first 
      b = memoryCache.get(cacheKey); 
      if(b == null){ 
       //memory cache was null, check file cache   
       b = diskLruImageCache.getBitmap(cacheKey); 

       // this is where it needs to be added to your memory cache 
       if(b != null){ 
        memoryCache.put(url, b); 
       } 
      } 



     return b; 
    } 
9

La ragione per cui non stai ricevendo alcun risultato perché il comportamento predefinito in Volley per la cache del disco dipende dal HTTP intestazioni dell'elemento che stai richiedendo (nel tuo caso un'immagine).

Il modo in cui funziona è Volley:

  1. ImageLoader controlla la cache L1 per un'immagine (memoria cache da Lei forniti al ImageLoader nel suo costruttore). Se disponibile, restituisci l'immagine.
  2. Richiesta elaborata da RequestQueue. Controlla la L2 (cache del disco) per l'immagine.
  3. Se trovato nella cache del disco, controllare il tempo di scadenza dell'immagine. Se non è scaduto, restituire.
  4. Scaricare l'immagine e restituirla.
  5. Salva immagine in cache.

Se si desidera che le impostazioni predefinite per lavorare, le immagini devono avere una Cache-Control intestazione come max-age=??? dove i punti interrogativi indicano abbastanza secondi dal momento in cui è stato scaricato.

Se si desidera modificare il comportamento predefinito, non sono sicuro, ma penso che sia necessario modificare il codice un po '.

Esaminare la classe CacheDispatcher nella fonte Volley.

1

Ho rintracciato questo problema nella mia app di oggi. Stavo impostando una dimensione massima della cache in KB nel costruttore, ma riportando una dimensione in byte in sizeOf(), quindi non è stato mai memorizzato nella cache.

This answer impostare me dritto.

0

Volley non memorizza nulla nella cache, se il controllo della cache non è impostato nell'intestazione della risposta.

Verificare l'implementazione della classe HttpHeaderParser in Volley.

Il caching può essere basato su max-age o E-tag. Controlla la tua intestazione di risposta e identifica qualsiasi cosa impostata lì. Assomiglierà a questo.

Cache-Control → pubblico, max-age = 300

Cache Header info

1

Probabilmente si sta utilizzando NetworkImageView per caricare le immagini. È possibile utilizzare ImageView e ImageLoader per fare la stessa cosa. Utilizzando ImageLoader i metadati nella chiave sono come "# W0 # H0" per qualsiasi dimensione dell'immagine.

ImageLoader imageLoader = getImageLoader(); 
imageLoader.get(url, ImageLoader.getImageListener(imageView, defaultDrawable, errorDrawable)); 
Problemi correlati