希望这不会太啰嗦,但尽量完整:
所以我在 Android 电子市场上有一个应用程序。在应用程序中有一些可序列化的类。应用程序在任何地方都运行良好(在模拟器中、在调试手机上、在下载该应用程序的手机上)。
我决定添加一些功能。这些功能涉及在我的一个 Serializable 类上实现 Comparable。在 Eclipse(模拟器或附加电话)中,更改似乎有效。也根据this Java document ,我认为这些更改是对可序列化类的有效更改。
现在来解决问题。似乎在导出已签名的 apk 后,我的应用程序崩溃了。第一次接触更改的类时会发生崩溃。堆栈跟踪被混淆了,细节不太重要(我认为),但它是一个 NullPointerException 导致应用程序崩溃。
这是我实验中修改后的代码:
比较版本:
public class Card implements Serializable, Comparable<Card>{
使用添加的方法:
public int compareTo(Card another) {
if( another.getName() == null ) return -1;
if( this.getName() == null ) return 1;
return this.getName().compareTo(another.getName());
}
普通版/原始版:
public class Card implements Serializable/*, Comparable<Card>*/{
没有添加方法。
这些类在其他方面是相同的。请注意,getName() 返回一个字符串。
我做了以下实验:
- 从我的手机上完全卸载该应用。
- 在不对代码进行 Comparable 更改的情况下构建应用程序,并通过 Eclipse 在我的手机上运行。 (运行良好)。
- 实现 Comparable 更改并通过 Eclipse 在我的手机上运行。 (运行良好)。
这里没有问题。现在我导出了上述每个构建的签名版本。
- 从我的手机上完全卸载该应用。
- 导出应用程序的签名版本,无需进行可比更改。使用以下命令上传到手机:adb install com.myapp(运行良好)。
- 导出具有可比更改的应用签名版本。使用 adb 上传。访问之前保存的内容时崩溃(NullPointerException)。
作为完整性检查,我执行了以下操作:
- 从手机上完全卸载该应用。
- 安装具有可比更改的应用程序的导出签名版本。没问题。
请注意,不在步骤 1. 和 2. 之间卸载的原因是模拟最终用户在更新之间保留他/她的数据(这里的一个重要功能)。另请注意,上面的最终健全性检查让我相当确定这是对 Serializeable 类的更改的问题。
因此,基本问题是:签名、导出的应用程序与从 Eclipse 中运行的版本之间有什么区别?对 Serializable 类的有效更改是否会在导出后破坏应用程序?
最佳答案
看起来这是混淆导致的问题。您通过 Eclipse 运行的应用程序也已签名,只是使用了不同的 key /证书,因此没有真正的区别。如果您正在使用 ProGuard,导出“发布”版本也会混淆代码,并且在此过程中某些类或方法可能会被删除(如果 ProGuard 认为它们未被使用)。所以堆栈跟踪很重要,您需要找出 NPE 发生的确切位置。然后设置 ProGuard 忽略此类/方法并再次测试。
关于java - 在 Eclipse 调试器中运行的导出、签名的 apk 和版本之间的差异?导致问题的可序列化类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7296791/