3

我最近为我的 Eclipse Android 项目激活了 ProGuard。将外部库和动态引用的类添加到 proguard.cfg 后,我在构建 apk 时没有收到任何错误。但是,当我尝试启动已安装的应用程序时,我得到了 NoSuchMethodError。

我将其缩小到在主要活动的 onCreate 方法中调用的特定方法。为简化起见,下面是类和方法的样子(我省略了很多代码,但我认为这应该说明它):

public class TestMain extends TabActivity implements OnSharedPreferenceChangeListener{
    ...

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        testMethod();
    }
}

testMethod() 定义如下:

private void testMethod() {
    int charsLeft = maxPostMessageLength - someEditText.length();
    ...
}

当我删除“someEditText.length()”部分时,应用程序启动。所以,在我看来,找不到的方法是 EditText.length() 方法。但奇怪的是,当我从 testMethod 中删除“someEditText.length()”并将其直接放入 onCreate 方法时,该应用程序也会启动:

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        test = someEditText.length();
        testMethod();
    }

有谁知道我如何摆脱这个错误以及为什么我可以直接在 onCreate 方法中调用 someEditText.length() 而不是在 onCreate 方法调用的方法中?当然,如果不使用 Proguard,该应用程序也可以正常工作。

编辑:我尝试了 proguard.cfg 中的 -dontshrink、-dontobfuscate 和 -dontoptimzie 选项。使用 -dontoptimize 应用程序启动时不会出现错误。不过,究竟是什么导致了这个特定的错误,这还是很有趣的。

4

4 回答 4

1

Proguard 文档自豪地指出:“ProGuard 工具通过删除未使用的代码和重命名类来缩小、优化和混淆您的代码”。

好吧,在遇到您描述的运行时错误后,我放弃了它的“缩小”部分。我添加了行

-dontshrink

到 proguard.cfg

您可以通过检查文件 usage.txt 来查看哪些例程已从您的代码中删除。我很高兴地说,在我的项目中它总是丢失,这意味着代码被混淆但没有被删除。我现在没有收到任何运行时错误。

于 2011-01-17T10:55:19.247 回答
1

我偶然发现了一个可能的解决方案。好吧,它完全适用于我的情况,所以这是对原始问题的解决方案:今天,我用@Override 注释实现了一些代码,起初它不起作用。幸运的是,其他人已经遇到了同样的问题和一个简单的 Eclipse 相关解决方案: 将项目导入 Eclipse 后出现“必须覆盖超类方法”错误

现在,我想,如果我以前一直使用 Java 级别 1.5,为什么不再次尝试 ProGuard,没有 -dontoptimize 选项,现在我将它设置为 1.6。伤不起...

我能说什么,现在应用程序启动并且在方法中调用 EditText.length() 时我没有收到奇怪的错误。

于 2011-03-02T14:09:26.470 回答
0

如果得出的结论是该方法没有任何副作用,则优化器可能会删除该方法调用和该方法。它不应该创建不一致的代码,而且我不知道这样的问题。您应该检查它是否与最新版本的 ProGuard 一起存在。否则,您应该在 ProGuard 站点上提交错误报告,最好使用说明问题的小示例。

于 2011-02-06T22:18:37.457 回答
0

我遇到了与 OP 类似的问题,它最终成为我设置 -allowaccessmodification 的 proguard 配置选项,删除它解决了这个问题。

于 2011-08-17T10:05:27.243 回答