I get the next exception: Problem decoding into existing bitmap, when setting inBitmap
to true;
Caused by: java.lang.IllegalArgumentException: Problem decoding into existing bitmap
at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:460)
...
The interesting thing is that the same code fails in different places when running on:
- API: 4.4.2, Nexus 4
- API: 4.3.1, Samsung s3
This is my code which is a copy as it shown in this DevBytes: Bitmap Allocation video.
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, crashes on
BitmapFactory.decodeResource()
at// #1
- S3, passes the #1 and display the first image, but crashes later by clicking on image at
BitmapFactory.decodeResource()
at// #2
Few notes:
- The images are in the same size. I tried
jpg
andpng
. Fails on both. - Bitmaps are mutable.
- I checked by using this
canUseForInBitmap
method, as described here.
Question:
How to use this inBitmap
property properly?
If you met such problem or you see that I made something stupid, please comment/reply. Any help, will be appreciated. If you know about any workaround, it will be great.
- Edit (the question is still open) -
Sorry for not explaining the reason of why I am trying to reuse bitmaps in such way.
The reason for this is GC that locks every time he decides to free memory.
inBitmap
feature should help us to reuse bitmap without allocating new memory which will cause GC to clean the already allocated memory.
For example if I use this common approach:
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);
Then this will be GC work:
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
This is more than 100ms of locked main thread!
The same thing will happen if I will decodeResource()
without the inBitmap
option. So the question is still open, how to use this property ?
setImageResource()
is bad and why I am trying to useinBitmap
flag – Modeling