Sto riscontrando un problema con bitmap su un'applicazione Android su cui sto lavorando. Ciò che si suppone accada è che l'applicazione scarica le immagini da un sito Web, le salva sul dispositivo, le carica in memoria come bitmap in un arraylist e le visualizza all'utente. Funziona tutto bene quando l'applicazione viene avviata per la prima volta. Tuttavia, ho aggiunto un'opzione di aggiornamento per l'utente in cui sono state eliminate le immagini e il processo descritto sopra inizia dappertutto.Errore "Trying to use bitmap recycled" per Android?
Il mio problema: utilizzando l'opzione di aggiornamento le vecchie immagini erano ancora in memoria e avrei rapidamente ottenuto OutOfMemoryErrors. Quindi, se le immagini vengono aggiornate, l'ho fatto scorrere attraverso l'arrayylist e riciclare le vecchie immagini. Tuttavia, quando l'applicazione va a caricare le nuove immagini nell'array, si blocca con un errore "Tentativo di utilizzare la bitmap riciclata".
Per quanto ne so, riciclare una bitmap distrugge la bitmap e libera la sua memoria per altri oggetti. Se voglio usare di nuovo la bitmap, deve essere reinizializzata. Credo che lo sto facendo quando i nuovi file vengono caricati nell'arrayylist, ma qualcosa è ancora sbagliato. Qualsiasi aiuto è molto apprezzato in quanto è molto frustrante. Il codice problema è sotto. Grazie!
public void fillUI(final int refresh) {
// Recycle the images to avoid memory leaks
if(refresh==1) {
for(int x=0; x<images.size(); x++)
images.get(x).recycle();
images.clear();
selImage=-1; // Reset the selected image variable
}
final ProgressDialog progressDialog = ProgressDialog.show(this, null, this.getString(R.string.loadingImages));
// Create the array with the image bitmaps in it
new Thread(new Runnable() {
public void run() {
Looper.prepare();
File[] fileList = new File("/data/data/[package name]/files/").listFiles();
if(fileList!=null) {
for(int x=0; x<fileList.length; x++) {
try {
images.add(BitmapFactory.decodeFile("/data/data/[package name]/files/" + fileList[x].getName()));
} catch (OutOfMemoryError ome) {
Log.i(LOG_FILE, "out of memory again :(");
}
}
Collections.reverse(images);
}
fillUiHandler.sendEmptyMessage(0);
}
}).start();
fillUiHandler = new Handler() {
public void handleMessage(Message msg) {
progressDialog.dismiss();
}
};
}
reg. "In realtà non è necessario chiamare il metodo di riciclo qui". Hm, interessante. Finora quello che ho letto sul web, ho anche pensato che fosse il modo di farlo e dovrebbe essere chiamato. L'ho sempre definito anche io. Ho anche riscontrato problemi di memoria quando utilizzo molte bitmap. Un buon modo per ridurre i problemi di memoria è usare le cache SoftReference, come suggerito da Romain Guy. Lo usa ad esempio in http://shelves.googlecode.com/svn/trunk/Shelves/src/org/curiouscreature/android/shelves/util/ImageUtilities.java Informazioni su SoftReferences: http: //java.sun. it/j2se/1.5.0/docs/api/java/lang/ref/SoftReference.html –
Il riciclo è buono ma non è richiesto. GC pulirà comunque la memoria. Riciclare lo pulirà più velocemente. Questo è il modo in cui lo capisco. – Fedor
Grazie Fedor! Mi sono assicurato di annullare tutte le viste che utilizzavano le bitmap prima di cancellare e ricreare l'array e questo ha fatto il trucco. :) – Mike