Я получаю следующее исключение: Дешифрование задачи в существующее растровое изображение при установке inBitmap
в true;
Вызвано: java.lang.IllegalArgumentException: проблема декодирования в существующую растровое изображение
на android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:460)
...
Интересно, что тот же код не работает в разных местах при запуске:
- API: 4.4.2, Nexus 4
- API: 4.3.1, Samsung s3
Это мой код, который является копией, как показано в этом видео DevBytes: Bitmap Allocation.
private BitmapFactory.Options options;
private Bitmap reusedBitmap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ImageView imageView = (ImageView) findViewById(R.id.image_view);
// set the size to option, the images we will load by using this option
options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
options.inMutable = true;
BitmapFactory.decodeResource(getResources(), R.drawable.img1, options);
// we will create empty bitmap by using the option
reusedBitmap = Bitmap.createBitmap(options.outWidth, options.outHeight, Bitmap.Config.ARGB_8888);
// set the option to allocate memory for the bitmap
options.inJustDecodeBounds = false;
options.inSampleSize = 1;
options.inBitmap = reusedBitmap;
// #1
reusedBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.img1, options);
imageView.setImageBitmap(reusedBitmap);
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
options.inBitmap = reusedBitmap;
// #2
reusedBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.img2, options);
imageView.setImageBitmap(reusedBitmap);
}
});
}
- Nexus 4, сбой на
BitmapFactory.decodeResource()
на// #1
- S3, передает # 1 и отображает первое изображение, но позже падает, нажимая на изображение
BitmapFactory.decodeResource()
на// #2
Несколько заметок:
- Изображения имеют одинаковый размер. Я пробовал
jpg
иpng
. Не работает на обоих. - Растровые изображения изменяемы.
- Я проверил с помощью этого метода
canUseForInBitmap
, описанного здесь .
Вопрос:
Как правильно использовать это свойство inBitmap
?
Если вы столкнулись с такой проблемой или видите, что я сделал что-то глупое, прокомментируйте/ответьте. Любая помощь будет оценена. Если вы знаете о каком-либо обходном пути, это будет здорово.
- Изменить (вопрос все еще открыт) -
Извините, что не объяснил причину, почему я пытаюсь повторно использовать растровые изображения таким образом.
Причина этого - GC, которая блокируется каждый раз, когда он решает освободить память.
Функция inBitmap
должна помочь нам повторно использовать растровое изображение без выделения новой памяти, которая заставит GC очистить уже выделенную память.
Например, если я использую этот общий подход:
Log.i("my_tag", "image 1");
imageView.setImageResource(R.drawable.img1);
Log.i("my_tag", "image 2");
imageView.setImageResource(R.drawable.img2);
Log.i("my_tag", "image 3");
imageView.setImageResource(R.drawable.img3);
Тогда это будет работа GC:
I/my_tag ( 5886): image 1
D/dalvikvm( 5886): GC_FOR_ALLOC freed 91K, 2% free 9113K/9240K, paused 15ms, total 15ms
I/dalvikvm-heap( 5886): Grow heap (frag case) to 19.914MB for 11520016-byte allocation
D/dalvikvm( 5886): GC_FOR_ALLOC freed <1K, 1% free 20362K/20492K, paused 13ms, total 13ms
I/my_tag ( 5886): image 2
D/dalvikvm( 5886): GC_FOR_ALLOC freed 11252K, 2% free 9111K/9236K, paused 15ms, total 15ms
I/dalvikvm-heap( 5886): Grow heap (frag case) to 19.912MB for 11520016-byte allocation
D/dalvikvm( 5886): GC_FOR_ALLOC freed <1K, 1% free 20361K/20488K, paused 35ms, total 35ms
I/my_tag ( 5886): image 3
D/dalvikvm( 5886): GC_FOR_ALLOC freed 11250K, 2% free 9111K/9236K, paused 15ms, total 15ms
I/dalvikvm-heap( 5886): Grow heap (frag case) to 19.913MB for 11520016-byte allocation
D/dalvikvm( 5886): GC_FOR_ALLOC freed <1K, 1% free 20361K/20488K, paused 32ms, total 32ms
Это более чем 100 мсек заблокированного основного потока!
То же самое произойдет, если я буду decodeResource()
без опции inBitmap
. Итак, вопрос по-прежнему открыт, как использовать это свойство?