Differences in an exported, signed apk and version running in Eclipse debugger? Serializeable class causing problems
Hopefully this won't be too long-winded, but trying to be complete:
So I have an app on the Android Market. Within the app are a few Serializable classes. App is working fine everywhere (in emulator, on debugging phone, on phones that download the app).
I made a decision to add some features. Those features involve implementing Comparable on one of my Serializable classes. In Eclipse (emulator or attached phone), the changes seem valid. Also according to this Java document, I think the changes are valid changes to a Serializable class.
Now to the problem. It seems that after exporting a signed apk, I have crashes in the app. The crashes occur the first time the altered class is touched. The stack trace is obfuscated, and the details aren't too important (I think), but it is a NullPointerException crashing the app.
Here is the changed code from my experiments:
The Comparable version:
public class Card implements Serializable, Comparable<Card>{
with the added method:
public int compareTo(Card another) {
if( another.getName(开发者_JS百科) == null ) return -1;
if( this.getName() == null ) return 1;
return this.getName().compareTo(another.getName());
}
The Regular/Original Version:
public class Card implements Serializable/*, Comparable<Card>*/{
without the added method.
The classes are identical otherwise. Note that getName() returns a String.
I performed the following experiment:
- Uninstall the app completely from my phone.
- Build the app without the Comparable change to the code and run on my phone through Eclipse. (runs fine).
- Implement the Comparable change and run on my phone through Eclipse. (runs fine).
No problems here. Now I exported a signed version of the each build described above.
- Uninstall the app completely from my phone.
- Export signed version of app without Comparable change. Upload to phone using: adb install com.myapp (runs fine).
- Export signed version of app WITH Comparable change. Upload using adb. Crash upon accessing previously saved (NullPointerException).
And as a sanity check I did the following:
- Uninstall the app completely from phone.
- install the exported, signed version of the app WITH Comparable change. No problems.
Note that the reason for NOT uninstalling in between steps 1. and 2. is to simulate the end user preserving his/her data between updates (an important feature here). Also note that the final sanity check above leads me to feel fairly certain it is an issue with the change to the Serializeable class.
So the fundamental questions are: What are the differences between a signed, exported app versus a version run from within Eclipse? Is there a reason that a valid change to a Serializable class would break the app after export?
It looks like this is a problem caused by obfuscating. The app you run through Eclipse is also signed, just with a different key/certificate, so no real difference there. If you are using ProGuard, exporting a 'release' version will also obfuscate the code, and in the process some classes or method might get removed (if ProGuard thinks they are not used). So the stack trace is important, and you need to find out where exactly the NPE is happening. Then setup ProGuard to ignore this class/method and test again.
精彩评论