2010-06-13 13 views
19

Çalıştığım bir Android uygulamasında bitmapler ile ilgili bir sorunla karşılaşıyorum. Uygulamanın bir web sitesinden görüntüleri indirip, cihaza kaydedip, bir arraylist içine bitmap olarak belleğe yüklediği ve bunları kullanıcıya gösterdiği varsayılır. Bu uygulama ilk kez başlatıldığında iyi çalışır. Ancak, görüntülerin silindiği kullanıcı için bir yenileme seçeneği ekledim ve yukarıda özetlenen işlem her yerde başlıyor.Android "Geri dönüştürülmüş bitmap kullanmaya çalışmak" hatası?

Sorunum: Yenileme seçeneğini kullanarak eski görüntüler bellekte kalıyordu ve hızlı bir şekilde OutOfMemoryErrors elde edecektim. Böylece, görüntüler yenilenirse, arraylist üzerinden koştum ve eski görüntüleri geri dönüştürdüm. Ancak, uygulama yeni görüntüleri arraylist'e yüklediğinde, "Geri dönüştürülmüş bitmap kullanmaya çalışmak" hatası ile çöküyor.

Anladığım kadarıyla, bir bitmap'in geri dönüştürülmesi bitmapi yok eder ve hafızasını diğer nesneler için boşaltır. Bitmap'i tekrar kullanmak istersem, yeniden başlatılmalıdır. Yeni dosyalar arraylist'e yüklendiğinde bunu yapıyorum, ama bir şey hala yanlış. Bu çok sinir bozucu olduğundan, herhangi bir yardım büyük beğeni topluyor. Sorun kodu aşağıda. Teşekkür ederim!

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(); 
    } 
}; 

}

cevap

19

Aslında burada geri dönüşüm yöntemi çağırmak gerekmez. Yenile düğmesi sadece diziyi temizlemeli, çöp toplayıcı daha sonra belleği boşaltacaktır. Eğer OutOfMemory alırsanız, bazı eski nesneler hala eski resimlerinize referans veriyor demektir ve Çöp Toplayıcı bunları kaldıramaz.

Bazı ImageView'ların bitmap'lerinizi görüntülediğini ve bu bitmap'lere başvurmalarını saklı tutarım. Hala görüntüleniyorken eski bitmap'leri kaldıramazsınız. Bu yüzden olası bir çözüm ImageVIews'i temizlemek. Bundan sonra diziyi temizleyebilir ve yeni görüntülerle doldurabilirsiniz.

Geri dönüşüm belleği boşaltır, ancak bazı ImageView hala bitmapi görüntülüyor ve geri dönüşümden sonra bunu yapamaz, bu yüzden "geri dönüştürülmüş bitmap kullanmaya çalışıyorsunuz".

Bunların tümü yalnızca bir varsayımdır çünkü tam kodunuzu göremiyorum.

+3

reg. "Burada geri dönüşüm yöntemini çağırmanıza gerek yok". Hm, ilginç. Şimdiye kadar internette okuduğum şeyi de yapmanın ve bunun çağrılmasının bir yol olduğunu düşündüm. Ben de her zaman böyle diyordum. Çok sayıda Bitmap kullanırken Bellek sorunları yaşadım. Bellek sorunlarını azaltmanın iyi bir yolu, Romain Guy'ın önerdiği gibi SoftReference önbelleklerini kullanmaktır. Örneğin, http://shelves.googlecode.com/svn/trunk/Shelves/src/org/curiouscreature/android/shelves/util/ImageUtilities.java SoftReferences hakkında: http: //java.sun. com/j2se/1.5.0/docs/aPI/java/lang/ref/SoftReference.html –

+4

Geri Dönüşüm iyi ama bu zorunlu değildir. GC yine de belleği temizleyecektir. Geri dönüşüm sadece daha hızlı temizleyecektir. Anladığım kadarıyla. – Fedor

+1

Teşekkür ederiz Fedor! Diziyi temizlemeden ve yeniden oluşturmadan önce bitmapleri kullanan tüm görünümleri boş bıraktığımı ve hile yaptığını emin oldum. :) – Mike

4

Bellek çok büyükse, bitmapi kendiniz geri dönüştürmeniz daha iyi olur. GC, kontrol edilemez.

İlgili konular