My company was sending an update to the Amazon app store when we got a rejection notice. The notice claimed that whenever you started our app, it would immediately crash. It didn't give a stacktrace; just the list of devices they tested it on. This was weird to us since the code was extensively tested. I grabbed the APK, side-loaded it onto my phone and it crashed! Unfortunately I couldn't get a stacktrace since this was a release build.
It took us a while to debug the problem. At first, I decompiled the APK but the decompiler didn't work. Most of our java files were missing. I just thought it was a problem with the decompiler. Eventually we decided to change the AndroidManifest.xml file in the jar to make it debuggable. The first surprise was that the AndroidManifest.xml was binary, not xml. The easy solution was to change the source AndroidManifest.xml, re-export, then take the binary AndroidManifest.xml from the newly exported APK and drop it into the broken APK. We resigned, but Android refused to install the APK. This was a learning process for us. We learned that you can't just re-sign an APK. You have to delete everything in the META-INF/* folder. That "un-signs" the APK file. We signed it and were able to install the APK. We crashed and got a stacktrace: NoClassDefFoundError. It turns out that "problem" with the decompiler was actually a problem with the export process. The export silently failed.
For those of you who are not familiar with the Amazon app store submission process, you have to upload an unsigned APK. Amazon adds a jar file and modifies every single Activity adding hooks into their DRM system. They do this regardless of whether you use their DRM or now. After they add their DRM, you download the new unsigned APK, sign it with your key, then upload the new signed APK back to the Amazon store. This weird process exists because Amazon wants to inject their DRM and they can't do that to a signed APK; since that would defeat the purpose of signing.
Lets examine that process for a second. Once you export an unsigned APK, you cannot test it. Unsigned APKs can't be installed onto phones. Once you sign it, in theory, you can install it, but the Amazon DRM kicks in, preventing us from testing it. This means we sent an APK to Amazon where we tested the code, but not the export process.
After some Googling, I discovered that the export process sometimes fails like this. It is usually associated with a corrupt bin/ folder in your Eclipse workspace. Cleaning your bin/ folder and rebuilding fixes the issue. This was the first attempt to package the APK from Windows. As it turns out, the bin/ folder corruption thing happens more frequently in Windows.
To prevent future problems, I recommended that we export a signed APK as the first step. This lets us test the app on a device. We can unsign the APK before uploading it the first time to the Amazon store. This gives us an opportunity to test the export process before uploading.
While being a horrible experience, we learned a lot. Although I signed jar files before, I never actually knew what actually changed in the jar file. Now we know there are two CERT files in the META-INF folder as well as a bunch of SHA-1 hashes in the MANIFEST.MF. Deleting those files (well the certs and the hashes from the manifest) will effectively unsign the jar. The coworker I was working with didn't realize that APK files were just zip files, so that was a good lesson for her. We figured out how to enable debugging on a released APK file. It was a really good learning experience.
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.