2011-11-02 15 views
20

La mia app può caricare immagini piuttosto grandi. In uno sforzo per essere memoria-conservatore, sto cercando di utilizzare una bitmap temporanea per il carico e un altro per l'immagine finale dopo la trasformazione:Android: errore "tentativo di utilizzare una bitmap riciclata" con bitmap temporanee

..... 
finalBitmap.recycle(); 
finalBitmap = null; 
Bitmap tempBitmap = BitmapFactory.decodeStream(fin, ...); 
finalBitmap = Bitmap.createBitmap(tempBitmap, ....); 
imgview.setImageBitmap(finalBitmap); 
..... 

Ora, a questo punto abbiamo finito con tempBitmap, che era necessario solo per trasportare la bitmap decodificata alla fase di trasformazione in createBitmap. Quindi:

..... 
tempBitmap.recycle(); 
tempBitmap = null; 
..... 

E ... si blocca con un "tentativo di utilizzare una bitmap riciclato" errore proprio a causa del riciclo dei tempBitmap. tempBitmap non è stato visualizzato e viene utilizzato solo proprio lì.

Cosa non va? Devo solo usare "finalBitmap" in tutto e si basano su CreateBitmap per gestirla (finalBitmap = Bitmap.createBitmap (finalBitmap, ....))? Non riesco a vedere quale dipendenza continua da tempBitmap ci sarebbe che causerebbe un tale fallimento.

Edit: Sì, l'assegnazione nulla sembra comportare l'appropriata, eventuale raccolta dei rifiuti, ma sono perplesso sul perché riciclare() su una bitmap temperatura è così problematico in questo caso. Ho l'impressione che createBitmap() abbia un riferimento ad esso ma perché e per quanto tempo?

risposta

25

Direttamente dal Android documentation:

Restituisce una bitmap immutabile dal sottoinsieme specificato della sorgente bitmap. La nuova bitmap potrebbe essere lo stesso oggetto dell'origine oppure è possibile che sia stata eseguita una copia .

Sembra che le funzioni createBitmap abbiano il potenziale per riutilizzare la bitmap fornita. In questo caso, non è necessario riciclare la bitmap temporanea poiché la bitmap finale lo sta utilizzando. Una cosa che puoi fare è

if(tempBitmap != finalBitmap) { 
    tempBitmap.recycle(); 
} 

Questo dovrebbe riciclare solo il tempBitmap quando non è lo stesso del finalBitmap. Almeno questo sembra essere ciò che la documentazione sta implicando.

+1

Ho perso il fatto che potenzialmente è lo stesso oggetto. La mia impostazione di temp a null non causa effetti collaterali perché in realtà non rilascia l'oggetto, mentre recycle() lo influenza direttamente. Hmm. Accetto la tua risposta e spero che mi farai il favore di alzare la mia domanda (dal momento che penso che sia un po 'di informazioni utili per le persone). – MartyMacGyver

Problemi correlati