3

According to documentation here, A png resource should be converted to a BitmapDrawable. However I'm observing a strange behavior wherein a png file which has only black pixels in it is resulting in a crash because of ClassCastException (wrapped in InvocationTargetException) if I try to do the following in a Custom View's constructor :

  ...
  tempDrawable = typedArr.getDrawable(R.styleable.CustomView_src); // Source points to a png file
  Log.i("TestPNGToResource", "Canonical Class Name " + tempDrawable.getClass().getCanonicalName());
  tempBitmap = ((BitmapDrawable) tempDrawable).getBitmap();
  ...

I see the following logged on android 2.2 and 2.3

09-24 13:21:37.575: I/TestPNGToResource(532): Canonical Class Name android.graphics.drawable.ColorDrawable

Why is the resource not being converted to a BitmapDrawable?

500865
  • 6,920
  • 7
  • 44
  • 87
  • If the png has some colored pixels, is it still happening? Not sure if the png optimization of `aapt` could actually convert a solid colored image into a `ColorDrawable` or if that's an error while resolving your custom attributes – zapl Sep 24 '13 at 17:46
  • It doesn't happen for images which have colored pixels. If there was any error with custom attributes it should have failed on any device. It works as expected on Nexus 4 running 4.3. – 500865 Sep 24 '13 at 18:19

2 Answers2

3

This is an optimization performed by aapt. It is able to recognize images made of a single color and turn them into, well, a single color instead of a bitmap. This is more space-efficient, improves loading times, etc.

Romain Guy
  • 97,993
  • 18
  • 219
  • 200
  • 2
    For the record, is there any way of overriding this behavior, or is it necessary to check for it in code? – Geobits Sep 30 '13 at 17:35
  • According to the documentation here : http://developer.android.com/guide/topics/resources/drawable-resource.html#Bitmap , I am casting the drawable to BitmapDrawable which is resulting in a crash because in this case it is getting converted to ColorDrawable. – 500865 Sep 30 '13 at 17:47
  • 1
    The documentation is incorrect and should be updated. @Geobits: you'll have to check for it in code. – Romain Guy Sep 30 '13 at 17:48
  • Just for clarification, BitmapDrawable or ColorDrawable are the only possible cases right? – 500865 Sep 30 '13 at 17:58
  • To be clear, this function returns a Drawable, and that is all. You should *not* be making assumptions about what it returns beyond that. If you want a bitmap, then use this: http://developer.android.com/reference/android/graphics/BitmapFactory.html#decodeResource(android.content.res.Resources,%20int) – hackbod Oct 13 '13 at 05:33
  • Normally I wouldn't do this but my question has got very little views and I have no idea how to do it so would you be able to take a look at this [question](http://stackoverflow.com/questions/35729545/reflection-in-background-android) please? I would really appreciate it – Dan Mar 01 '16 at 17:51
0

i assume this won't occur for 9-patch images, right? also, when using the image file, will extracting the apk file still show the image file inside it?

anyway, i'm not sure if that helps, but have you tried to check this value:

TypedValue value = a.peekValue(R.styleable.CustomView_src);

then , if it's any of the color types, you can create your own drawable with this color. problem is how to get the size if that's what you get.

however, if in the special case you've shown, you get a reference type, you can probably force it to be BitmapDrawable by just creating the bitmap using BitmapFactory.decodeResource().

android developer
  • 114,585
  • 152
  • 739
  • 1,270
  • Normally I wouldn't do this but my question has got very little views and I have no idea how to do it so would you be able to take a look at this [question](http://stackoverflow.com/questions/35729545/reflection-in-background-android) please? I would really appreciate it – Dan Mar 01 '16 at 17:51