Wednesday, July 2, 2014

Colors Are Hard, Man

I ran into a pretty funny bug last night.  In this app, I am allowing users to change the background color.  The choice of background color is stored in a SharedPreference.  As you may know, every time you read from SharedPreferences, you have to provide a default value for the preference you are reading.  I was reading an int, so I used a default value of -1 to check if the preference was initialized or not.  My code looked like this:
However, the above exception was being thrown every single time, and I couldn't figure out why.  I double- and triple-checked the names for typos, just in case I was assigning to "backgronud" or something like that.  Nope, no typos.  So here's where I initialize the preference, in my main activity's onCreate:
I threw that log message in there to confirm that, yes, the preference was definitely getting initialized.  But then why was it going with the default -1 and throwing that exception?  I had to break out the debugger before I figured it out.

So, in Android, colors are stored as integers, (which are 32 bits,) with 8 bits for each channel: Alpha, Red, Green, and Blue.  So if you write out the value for a color in hex, it takes this format: 0xAARRGGBB.  So, for example, the color Green has a value of 0xFF00FF00, and White would be 0xFFFFFFFF.  Do you see the issue here?

If not, read up a bit on Two's Compliment and then come back here.

Done?  Good.

0xFFFFFFFF in 32-bit Two's Compliment is -1.  It was initializing to the same value that I was using to see if it was not initialized.  So it would start out at -1, and then throw the error because I thought that a color would never have a value of -1.  How wrong I was.

Of course, this is easily fixed by choosing a color value that actually will never be used.  I went with 0 instead of -1.  I could also just delete the error checking and make it default to white everywhere, but I prefer having the default value assigned in only one place, making it easier to change later.

No comments:

Post a Comment