14

自从我将 ADT 从 16 更新到 18(这要求 Proguard 从 4.6 更新到 4.8)以来,Proguard 的行为一直很奇怪(并且不一致?)。

最新的此类问题是当我尝试导出已签名(发布)的 APK 时,我收到以下错误:

Proguard returned with error code 1. See console
Warning: com.bta.LibProj2: can't find referenced class com.bta.R$string
Warning: com.bta.MyDlg1: can't find referenced class com.bta.R$string
Warning: com.bta.MyMenu: can't find referenced class com.bta.R$menu
Warning: com.bta.R: can't find referenced class com.bta.R$attr
Warning: com.bta.R: can't find referenced class com.bta.R$drawable
Warning: com.bta.R: can't find referenced class com.bta.R$menu
Warning: com.bta.R: can't find referenced class com.bta.R$string
Warning: com.bta.myapp.MyAppActivity$1: can't find referenced class com.bta.myapp.MyAppActivity
Warning: com.bta.myapp.MyAppActivity$ELicenseResponse: can't find referenced class com.bta.myapp.MyAppActivity
Warning: com.bta.myapp.MyAppActivity$MyLicenseCheckerCallback$1: can't find referenced class com.bta.myapp.MyAppActivity$MyLicenseCheckerCallback
Warning: com.bta.myapp.MyAppActivity$MyLicenseCheckerCallback$1: can't find referenced class com.bta.myapp.MyAppActivity
Warning: com.bta.myapp.R$array: can't find referenced class com.bta.myapp.R
Warning: com.bta.myapp.R$layout: can't find referenced class com.bta.myapp.R
Warning: com.bta.myapp.R$xml: can't find referenced class com.bta.myapp.R
Warning: there were 49 unresolved references to classes or interfaces.
         You may need to specify additional library jars (using '-libraryjars').
java.io.IOException: Please correct the above warnings first.
    at proguard.Initializer.execute(Initializer.java:321)
    at proguard.ProGuard.initialize(ProGuard.java:212)
    at proguard.ProGuard.execute(ProGuard.java:87)
    at proguard.ProGuard.main(ProGuard.java:493)

我确实注意到了添加-libraryjarsproguard.cfg 的建议,但我以前从未需要这样做(而且我没有更改代码中的任何内容,我所做的只是将 Proguard 从 4.6 更新到 4.8)。这是否表明我的开发环境配置有问题?

此外,我检查了 Proguard 的疑难解答部分中的Can't find referenced class:它指的是忘记或忽略指定一个库-libraryjars(我承认),但我从未指定任何库,它以前一直有效!发生了什么变化?

我的 proguard.cfg 文件顺便说一句以:

-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

知道发生了什么吗?为什么 Proguard 开始让我这么难受?(我已经用它顺利滑行了一年多)我的系统配置中是否缺少一些基本的东西?

顺便说一句,我确实尝试通过在行中指定所有库来添加我一直在使用的库-libraryjars,但 Proguard 的行为只会变得更糟:它会失败而不会给出我上面引用的任何错误日志。

4

3 回答 3

15

问题解决了。在 SO 中搜索了很多线索后,我终于找到了 Proguard 开发人员本人的这个提示

-dontwarn scala.**

我没有使用任何包含“scala”的东西,我也不知道 scala 是什么。但这让我想到了-dontwarn我自己的应用程序包上放置一个:

-dontwarn com.bta.**

那成功了。

作为记录,导致我找到这个提示的搜索短语是:proguard admob "can't find referenced class"

PS Proguard 的建议You may need to specify additional library jars (using '-libraryjars')甚至没有朝着正确的方向发展……

更新:虽然-dontwarn com.bta.**允许生成签名的 APK,但当我尝试使用以下命令启动它时它就崩溃了:

ClassNotFoundException: com.bta.myapp.MyAppActivity in loader dalvik.system.PathClassLoader[/data/app/com.bta.myapp.myapp-1.apk]. 

什么样的恶梦。

更新2: -dontwarn com.bta.**结果过于包容。我将其更改为:

-dontwarn com.bta.myapp.MyAppActivity.R**

现在一切都运行良好,没有发生任何事故。 什么样的恶梦。

在浪费了太多时间来调试应该可以节省我时间的工具之后,我发现了问题的根源。这是 Android SDK 工具中的一个错误。它被记录为已在 r17 中解决,但我使用的是今天最新的(2012 年 6 月 18 日),但尚未解决!(见评论 24)。评论 25还描述了允许我现在进行实际开发的解决方法。

错误是复杂系统中的事实。但是,Proguard 和向 Proguard 提供输入的构建工具都不能提供任何有用的错误消息(实际上它们完全相反),这表明谷歌推荐的 Android 开发工具的“方法论”存在某些问题。

于 2012-06-13T04:45:23.737 回答
1

在 SDK 和 ADT 的最新更新后,我遇到了类似的问题,最终需要我从头开始检查我的项目。尝试检查项目的新副本,看看是否可行。

于 2012-06-12T23:45:28.520 回答
1

首先,调查 Proguard 告诉您的内容:

Warning: com.bta.LibProj2: can't find referenced class com.bta.R$string
Warning: com.bta.MyDlg1: can't find referenced class com.bta.R$string

它找不到 com.bta.R$string。为什么不?com.bta.R$string 在那里吗?不是源代码,我们现在不关心源代码。.class 文件在那里吗?如果它在文件系统中,它实际上是否在 Proguard 配置文件中被引用?确保你知道它应该如何被包括在内;什么是引用 com.bta.R$string?您可能会使用 javap 来解决这个问题。

在这种情况下使用更好的大锤不是关闭警告(因为它们实际上是在警告您一些重要的事情),而是告诉 Proguard 保留缺少的 com.bta 类,如下所示:

-keep class com.bta.**

考虑图书馆罐子的建议只是一个建议。这显然是 proguard 的常见错误配置,因此添加注释以将人们指向该方向是完全合理的。它没有解决您的问题,但这并不意味着它不是有用的建议。

顺便说一句,我确实尝试通过在 -libraryjars 行中指定所有这些库来添加我一直在使用的库,但是 Proguard 的行为只会变得更糟:它会失败而不会给出我上面引用的任何错误日志。

您可能需要那些 -libraryjars 条目。他们不会让问题变得更糟。您已经从有 N 个错误(未指定 -libraryjars)的配置转变为有 N - 1 个错误的配置。修复 N - 1 解决方案。如果有的话,它会给出什么错误?如果没有错误,如果重新打开警告会发生什么?

仅限专家:实际上,您可以在没有 -libraryjars 条目的情况下进行有用的配置,但您需要完全了解Proguard 对您的代码所做的确切操作。在我的脑海中,除了性能之外,我想不出任何理由来解释你为什么要这样做。

于 2012-06-15T21:40:50.900 回答