Только Android 4.1, Bitmap перерабатывается автоматически

У меня очень критическая проблема. Только Android 4.1, Bitmap перерабатывается автоматически! Я не вызывал recycle() в своем коде! Мой проект отлично работает в других версиях ОС (~4.0.3) с любыми разрешениями. В других проектах такая же проблема.

Все файлы изображений находятся в папке drawable-nodpi. Я изменил их размер, чтобы они соответствовали разрешению любых устройств, всегда.

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

В моем тестировании,

  • Тот же экземпляр растрового изображения, но проблема возникает в зависимости от значения изменения размера.

например) ширина интервала = 100;

Растровое изображение imgStar = MyResourceManager.getInstance().GetScaledBitmap(R.drawable.star, ширина, ширина, правда); -> возвращает переработанный экземпляр.

ширина = 200;

imgStar = MyResourceManager.getInstance().GetScaledBitmap(R.drawable.star, ширина, ширина, правда); -> возвращает обычный экземпляр.

  • В разных разрешениях imgStar работает нормально, но проблема возникает в другом экземпляре растрового изображения. Точно так же, когда я меняю значение изменения размера, все работает нормально.

  • В том же разрешении проблема возникает в другом экземпляре растрового изображения, если я изменяю имя папки с файлами изображений. drawable-nodpi -> drawable -> drawable-ldpi,..., drawable-xdpi.

  • То же значение изменения размера, оно отлично работает, если я поставлю другой идентификатор ресурса. бывший)

целая ширина = 100;

Растровое изображение imgStar = MyResourceManager.getInstance().GetScaledBitmap(R.drawable.звездочка, ширина, ширина, правда); -> возвращает переработанный экземпляр.

imgStar = MyResourceManager.getInstance().GetScaledBitmap(R.drawable.алмаз, ширина, ширина, правда); -> возвращает обычный экземпляр.

Пожалуйста... что я могу сделать?! Т ^ Т


person user1746071    schedule 15.10.2012    source источник
comment
Этот вопрос аналогичен и может иметь ваш ответ: заголовок stackoverflow.com/questions/7983321/   -  person XdebugX    schedule 06.12.2012


Ответы (3)


Причина, по которой вы получаете разные результаты для разных размеров, может заключаться в том, что createScaledBitmap вернет исходный объект, если он имеет тот же размер, до которого вы масштабируете.

У меня была такая же проблема, я делал то же самое, что и вы. Я смог исправить это следующим образом:

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

Здесь я скопировал растровое изображение, чтобы убедиться, что это не просто ссылка на объект растрового изображения tmp, прежде чем я переработал растровое изображение tmp. Конечно, вы можете использовать любую конфигурацию растрового изображения, которая вам нужна.

person XdebugX    schedule 06.12.2012

Я считаю, что XdebugX был прав в своем выводе, хотя вам не нужно создавать копию. Просто проверьте, совпадают ли ячейки памяти между измененными и исходными растровыми изображениями.

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

Я бы предпочел попробовать проверить, не было ли уже переработано растровое изображение, прежде чем перерабатывать:

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