3

希望这不会太啰嗦,但尽量完整:

所以我在 Android Market 上有一个应用程序。应用程序中有一些可序列化的类。应用程序在任何地方都运行良好(在模拟器中、在调试手机上、在下载应用程序的手机上)。

我决定添加一些功能。这些功能涉及在我的一个 Serializable 类上实现 Comparable。在 Eclipse(模拟器或附加电话)中,更改似乎是有效的。同样根据this Java document,我认为这些更改是对 Serializable 类的有效更改。

现在来解决问题。似乎在导出签名的 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() 返回一个字符串。

我进行了以下实验:

  1. 从我的手机上完全卸载该应用程序。
  2. 在没有对代码进行可比较更改的情况下构建应用程序,并通过 Eclipse 在我的手机上运行。(运行良好)。
  3. 通过 Eclipse 实现 Comparable 更改并在我的手机上运行。(运行良好)。

这里没有问题。现在我导出了上述每个构建的签名版本。

  1. 从我的手机上完全卸载该应用程序。
  2. 导出应用程序的签名版本而不进行可比更改。使用: adb install com.myapp 上传到手机(运行良好)。
  3. 导出具有可比较更改的应用程序签名版本。使用 adb 上传。访问以前保存的 (NullPointerException) 时崩溃。

作为健全性检查,我做了以下事情:

  1. 从手机上完全卸载应用程序。
  2. 安装导出的、签名版本的应用程序 WITH Comparable change。没问题。

请注意,在步骤 1. 和 2. 之间不卸载的原因是模拟最终用户在更新之间保留他/她的数据(这里的一个重要功能)。另请注意,上面最后的健全性检查让我相当确定这是对 Serializeable 类的更改的问题。

所以基本问题是:签名的、导出的应用程序与在 Eclipse 中运行的版本之间有什么区别?是否有理由对 Serializable 类进行有效更改会在导出后破坏应用程序?

4

1 回答 1

2

看起来这是一个由混淆引起的问题。您通过 Eclipse 运行的应用程序也已签名,只是使用不同的密钥/证书,因此没有真正的区别。如果您使用 ProGuard,导出“发布”版本也会混淆代码,并且在此过程中某些类或方法可能会被删除(如果 ProGuard 认为它们未使用)。所以堆栈跟踪很重要,你需要找出 NPE 到底发生在哪里。然后设置 ProGuard 忽略此类/方法并再次测试。

于 2011-09-04T04:42:43.367 回答