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:
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);
}
});
}
BitmapFactory.decodeResource()
at // #1
BitmapFactory.decodeResource()
at // #2
jpg
and png
. Fails on both.canUseForInBitmap
method, as described here.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.
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 ?
I tried your code with emulated Nexus 4.
I had default ic_launcher.png file which I copy and pasted it two times in drawable-mdpi (as I usually do). I renamed the two new files to match the names in your code (so that I have less changes to make there).
When I run the application I observed the same as you did.
After few different attempts I decided to copy the the new pngs to other drawable folders - so they were present into:
I run the application and it is working!
I am not really sure why it really works, but obviously it has to be something with the correct screen resolution/density.