We came across a serious bug in Android this morning which I’d like to write about. The bug nearly bricked two of our test devices: one device became completely unresponsive as soon as we installed our app onto it, except for being able to tap the “Power Off” on-screen button after holding down the physical power button. The second device likewise became completely unresponsive once the homescreen app drawer button was tapped. Rebooting the devices did not help; the devices finish booting as the Android text is written across the screen, but then the screen stays black. We had to factory reset the devices from within the recovery menu, or uninstall the app via ADB.
First, the background: clients often come to us with an iOS app that they’d like transferred onto Android, and we were working on such a project this morning. Clients often don’t supply every graphical asset used in their iOS app, but we usually find it more convenient to simply extract the JPEG or PNG files from the IPA file rather than contacting them. This ensures we get the actual file used in their iOS version, and that the image will thus look the same. Extracting the images is fairly simple to do on a Mac: right click on the IPA, open it with “Archive Utility”, open the new “Payload” folder and right click on the file inside and choose “Show Package Contents”. You can now browse to find the image(s) you’re looking for.
There’s just one catch: iOS apps use a different, often incompatible, encoding for PNG images and worse yet, they keep the same file extension. I’m not sure why they do this, but I don’t think Apple needs a reason to be different. Luckily re-encoding the images into ‘normal’ PNG images is also simple: the Mac “Preview” program, which is the default program for opening images, has an Export command which does the job.
It’s forgetting to fix the peculiar encoding that caused the problem I first described. If you try to use the iOS-PNG in your Android app without converting the encoding, Android simply fails to open the image. Setting it to an ImageView via setImageResource behaves the same as providing an invalid resource ID; trying to open it through BitmapFactory returns null. This can be a bit confusing as the code compiles cleanly and the Mac’s image viewing programs can open the image without trouble, but ultimately it’s not terribly serious. However, if you set this image file as the app’s Launcher Icon, it becomes a major issue.
The default Launcher on Nexus devices apparently gets stuck trying to open the image; the image is just compatible enough where it thinks it should be able to open it, but it seems to get stuck in an infinite loop trying and failing to open the image. We encountered the fated “Application Not Responding” force close dialog for the “System UI” app. I’ve also had it reboot the device immediately after installing the app.
This affects Android 5.0 and 5.1. We tried it with an older version of Android (4.3) and it coped by replacing the app’s icon with the default green robot in the Launcher screen. If you want to test this for yourself, download this file and set it as the launcher icon in an app’s manifest. Using a simple text file with a PNG extension is not sufficient to cause this problem; Android recognises that it isn’t a valid image and provides a placeholder.
This is a serious bug in the Android launcher. It shouldn’t be possible for an individual app to get so close to bricking your device.