Hanya Android 4.1, Bitmap didaur ulang secara otomatis

Saya punya masalah yang sangat kritis. Hanya Android 4.1, Bitmap didaur ulang secara otomatis! Saya tidak memanggil recycle() dalam kode saya! Proyek saya berfungsi dengan baik di versi OS lain (~ 4.0.3) dengan resolusi apa pun. Proyek lain juga memiliki masalah yang sama.

Semua file gambar ada di folder drawable-nodpi. Saya selalu mengubah ukurannya agar sesuai dengan resolusi perangkat apa pun.

public Bitmap GetBitmap(int resource){

    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inDither = true;
    options.inPurgeable = true;

    Bitmap tmp = null;

    try{
        tmp = BitmapFactory.decodeResource(mResources, resource, options);
    }catch(OutOfMemoryError e){
        options.inSampleSize = 2;
        tmp = BitmapFactory.decodeResource(mResources, resource, options);
    }

    return tmp;
}

public Bitmap GetScaledBitmap(int resource, int width, int height, boolean filter){

    Bitmap tmp = GetBitmap(resource);

    Bitmap img = Bitmap.createScaledBitmap(tmp, width, height, filter);

    tmp.recycle();
    tmp = null;

    return img;
}

Dalam pengujian saya,

  • Contoh bitmap yang sama, tetapi masalah terjadi tergantung pada pengubahan ukuran nilai.

misal) int lebar = 100;

Bitmap imgStar = MyResourceManager.getInstance().GetScaledBitmap(R.drawable.star, lebar, lebar, benar); -> mengembalikan contoh daur ulang.

lebar = 200;

imgStar = MyResourceManager.getInstance().GetScaledBitmap(R.drawable.star, lebar, lebar, benar); -> mengembalikan contoh normal.

  • Dalam resolusi yang berbeda, imgStar berfungsi dengan baik, tetapi masalah terjadi pada contoh bitmap lainnya. Demikian pula, Saat saya mengubah nilai pengubahan ukuran, itu berfungsi dengan baik.

  • Dalam resolusi yang sama, masalah terjadi pada contoh bitmap lain, jika saya mengubah nama folder file gambar. drawable-nodpi -> drawable -> drawable-ldpi, ..., drawable-xdpi.

  • Nilai pengubahan ukuran yang sama, berfungsi dengan baik jika saya memasukkan id sumber daya lain. mantan)

int lebar = 100;

Bitmap imgStar = MyResourceManager.getInstance().GetScaledBitmap(R.drawable.star, width, width , true); -> mengembalikan contoh daur ulang.

imgStar = MyResourceManager.getInstance().GetScaledBitmap(R.drawable.diamond, lebar, lebar, benar); -> mengembalikan contoh normal.

Tolong... apa yang bisa saya lakukan?! T ^ T


person user1746071    schedule 15.10.2012    source sumber
comment
Pertanyaan ini serupa dan mungkin ada jawabannya: stackoverflow.com/questions/7983321/   -  person XdebugX    schedule 06.12.2012


Jawaban (3)


Alasan Anda mendapatkan hasil yang berbeda dari ukuran yang berbeda mungkin karena createScaledBitmap akan mengembalikan objek asli jika ukurannya sama dengan yang Anda skalakan.

Saya memiliki masalah yang sama, melakukan hal yang sama dengan Anda. Saya dapat memperbaikinya dengan cara ini:

public Bitmap GetScaledBitmap(int resource, int width, int height, boolean filter) {

    Bitmap tmp = GetBitmap(resource);
    Bitmap img = Bitmap.createScaledBitmap(tmp, width, height, filter);
    //copy the image to be sure you are not using the same object as the tmp bitmap
    img=img.copy (Bitmap.Config.RGB_565,false);
    tmp.recycle();
    tmp = null;
    return img;
}

Di sini saya menyalin bitmap untuk memastikan itu bukan hanya referensi ke objek bitmap tmp sebelum saya mendaur ulang bitmap tmp. Tentu saja Anda dapat menggunakan konfigurasi bitmap apa pun yang Anda perlukan.

person XdebugX    schedule 06.12.2012

Saya yakin XdebugX benar dalam temuannya meskipun Anda tidak perlu membuat salinannya. Cukup periksa apakah lokasi memori sama antara bitmap Anda yang diubah ukurannya dan bitmap asli.

public Bitmap GetScaledBitmap(int resource, int width, int height, boolean filter){

    Bitmap tmp = GetBitmap(resource);
    if (tmp == null) {
        return null;
    }

    Bitmap img = Bitmap.createScaledBitmap(tmp, width, height, filter);

    /***
     * Bitmap#createScaledBitmap will return the original object
     * if it is the same size you are scaling to.
     */
    if (tmp != img) {
        Log.d(TAG, "Full size image recycled");
        tmp.recycle();
    } else {
        Log.w(TAG, "Resized bitmap was the same as the fullsize bitmap");
    }

    return img;
}
person JRomero    schedule 07.06.2013

Saya lebih menyarankan untuk mencoba memeriksa apakah bitmap sudah didaur ulang sebelum didaur ulang:

if (!tmp.isRecycled()) tmp.recycle();
person USB    schedule 09.01.2013