android-studio - 使用 ProGuard 缩小时无法使用 Android Studio 构建 APK

标签 android-studio apk proguard

我在生成应用程序的 APK 时遇到问题。

如果我调试/运行应用程序,它可以正常工作。但是当我尝试生成相应的 APK 时,Android Studio 给了我很多警告和一个错误:

Note: there were 159 duplicate class definitions.
  (http://proguard.sourceforge.net/manual/troubleshooting.html#duplicateclass)
Warning:com.thoughtworks.xstream.converters.reflection.CGLIBEnhancedConverter$ReverseEngineeredCallbackFilter: can't find superclass or interface net.sf.cglib.proxy.CallbackFilter
Warning:org.apache.harmony.awt.datatransfer.DataProxy: can't find superclass or interface java.awt.datatransfer.Transferable
Warning:org.apache.harmony.awt.datatransfer.NativeClipboard: can't find superclass or interface java.awt.datatransfer.Clipboard
Warning:library class android.content.res.XmlResourceParser extends or implements program class org.xmlpull.v1.XmlPullParser
Warning:library class org.apache.http.auth.AuthenticationException extends or implements program class org.apache.http.ProtocolException
[...]
Warning:library class org.apache.http.impl.conn.LoggingSessionOutputBuffer extends or implements program class org.apache.http.io.SessionOutputBuffer
Warning:com.itextpdf.testutils.ITextTest: can't find referenced class javax.management.OperationsException
Warning:com.itextpdf.text.pdf.BarcodeCodabar: can't find referenced class java.awt.Color
[...]
Warning:com.itextpdf.text.pdf.security.MakeXmlSignature: can't find referenced class javax.xml.crypto.dsig.spec.C14NMethodParameterSpec
[...]
Warning:com.sun.mail.handlers.image_gif: can't find referenced class java.awt.datatransfer.DataFlavor
[...]
Warning:com.sun.mail.imap.protocol.IMAPSaslAuthenticator: can't find referenced class javax.security.sasl.Sasl
[...]
Warning:com.thoughtworks.xstream.converters.extended.ColorConverter: can't find referenced class java.awt.Color
[...]
Warning:org.apache.harmony.awt.ContextStorage: can't find referenced class java.awt.Toolkit
[...]
Warning:org.spongycastle.jce.provider.X509LDAPCertStoreSpi: can't find referenced class javax.naming.directory.InitialDirContext
[...]
Warning:library class android.content.Intent depends on program class org.xmlpull.v1.XmlPullParser
[...]
Warning:library class org.apache.http.client.HttpClient depends on program class org.apache.http.HttpResponse
[...]
Warning:library class org.xmlpull.v1.XmlPullParserFactory depends on program class org.xmlpull.v1.XmlPullParser
Warning:there were 1077 unresolved references to classes or interfaces.
         You may need to add missing library jars or update their versions.
         If your code works fine without the missing classes, you can suppress
         the warnings with '-dontwarn' options.
         (http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedclass)
Warning:there were 141 instances of library classes depending on program classes.
         You must avoid such dependencies, since the program classes will
         be processed, while the library classes will remain unchanged.
         (http://proguard.sourceforge.net/manual/troubleshooting.html#dependency)
Warning:there were 5 unresolved references to program class members.
         Your input classes appear to be inconsistent.
         You may need to recompile the code.
         (http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedprogramclassmember)
:vet:proguardInternalRelease FAILED
Error:Execution failed for task ':PROJECTNAME:proguardInternalRelease'.
> java.io.IOException: Please correct the above warnings first.
Information:BUILD FAILED
Information:Total time: 13.878 secs
Information:1 error
Information:679 warnings
Information:See complete output in console

该项目由一个库项目组成,在 settings.gradle 中作为外部项目导入:
include ':library'
project(':library').projectDir = new File(settingsDir, '../Library/library')

与所有依赖项。
build.gradle图书馆是
apply plugin: 'com.android.library'

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.2"

    defaultConfig {
        minSdkVersion 15
        targetSdkVersion 21
        multiDexEnabled true
    }

    packagingOptions {
        exclude 'META-INF/DEPENDENCIES'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/NOTICE.txt'
    }

}

dependencies {
    compile 'com.google.android.gms:play-services:+'
    compile 'com.android.support:support-v13:21.0.+'
    compile 'com.android.support:multidex:1.0.0'
    compile('ch.acra:acra:4.5.0') {
        exclude group: 'org.json'
    }
    compile 'org.apache.httpcomponents:httpcore:4.3'
    compile('org.apache.httpcomponents:httpmime:4.3.1') {
        exclude group: 'org.apache.httpcomponents', module: 'httpcore'
        exclude group: 'org.apache.httpcomponents', module: 'httpclient'
    }
    compile('javax.mail:mail:1.4.7') {
        exclude module: 'activation'
    }
    compile 'com.madgag.spongycastle:pkix:1.50.0.0'
    compile 'org.ccil.cowan.tagsoup:tagsoup:1.2.1'
    compile ('com.itextpdf.tool:xmlworker:5.5.1'){
        exclude module: 'itextpdf'
    }
    compile('com.thoughtworks.xstream:xstream:1.4.4') {
        exclude group: 'xmlpull', module: 'xmlpull'
    }
    compile 'com.google.zxing:core:3.0.1'
    compile files('libs/activation.jar')
    compile files('libs/additionnal.jar')
    compile files('libs/miniTemplator.jar')
    compile files('libs/itextg-5.5.1.jar')
}

和项目build.gradle
apply plugin: 'com.android.application'

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.2"

    defaultConfig {
        applicationId "my.package.name"
        minSdkVersion 15
        targetSdkVersion 21
        multiDexEnabled true
    }

    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    productFlavors {
        def BOOLEAN = "boolean"
        def TRUE = "true"
        def FALSE = "false"
        def A_FIELD= "A_FIELD"

        internal {
            buildConfigField BOOLEAN, A_FIELD, FALSE
        }

        official {
            buildConfigField BOOLEAN, A_FIELD, TRUE
        }
    }


    packagingOptions {
        exclude 'META-INF/DEPENDENCIES'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/NOTICE.txt'
    }
}

dependencies {
    compile project(':library')
}

afterEvaluate {
    tasks.matching {
        it.name.startsWith('dex')
    }.each { dx ->
        if (dx.additionalParameters == null) {
            dx.additionalParameters = []
        }
        dx.additionalParameters += '--multi-dex'
    }
}

如何修复它以便可以编译 APK?

编辑:在我的 proguard-rules.pro 中添加了很多 -dontwarn 选项后,我还是得到了错误,我无法解决这些警告(Here 有一些提示,但不是这些警告......) :
Warning:com.itextpdf.text.pdf.security.PdfPKCS7: can't find referenced method 'ASN1Integer(int)' in program class org.spongycastle.asn1.ASN1Integer
Warning:com.sun.activation.viewers.ImageViewer: can't find referenced method 'java.awt.Component add(java.awt.Component)' in program class com.sun.activation.viewers.ImageViewer
Warning:com.sun.activation.viewers.ImageViewer: can't find referenced method 'java.awt.Toolkit getToolkit()' in program class com.sun.activation.viewers.ImageViewer
Warning:com.sun.activation.viewers.ImageViewer: can't find referenced method 'void invalidate()' in program class com.sun.activation.viewers.ImageViewer
Warning:com.sun.activation.viewers.ImageViewer: can't find referenced method 'void validate()' in program class com.sun.activation.viewers.ImageViewer
Warning:com.sun.activation.viewers.ImageViewer: can't find referenced method 'void doLayout()' in program class com.sun.activation.viewers.ImageViewer
Warning:com.sun.activation.viewers.ImageViewerCanvas: can't find referenced method 'void invalidate()' in program class com.sun.activation.viewers.ImageViewerCanvas
Warning:com.sun.activation.viewers.ImageViewerCanvas: can't find referenced method 'void repaint()' in program class com.sun.activation.viewers.ImageViewerCanvas
Warning:com.sun.activation.viewers.TextEditor: can't find referenced method 'void setLayout(java.awt.LayoutManager)' in program class com.sun.activation.viewers.TextEditor
Warning:com.sun.activation.viewers.TextEditor: can't find referenced method 'void invalidate()' in program class com.sun.activation.viewers.TextEditor
Warning:com.sun.activation.viewers.TextViewer: can't find referenced method 'void setLayout(java.awt.LayoutManager)' in program class com.sun.activation.viewers.TextViewer
Warning:com.sun.activation.viewers.TextViewer: can't find referenced method 'java.awt.Component add(java.awt.Component)' in program class com.sun.activation.viewers.TextViewer
Warning:com.sun.activation.viewers.TextViewer: can't find referenced method 'void invalidate()' in program class com.sun.activation.viewers.TextViewer
Warning:javax.activation.ActivationDataFlavor: can't find referenced method 'boolean isMimeTypeEqual(java.awt.datatransfer.DataFlavor)' in program class javax.activation.ActivationDataFlavor
Warning:there were 14 unresolved references to program class members.
         Your input classes appear to be inconsistent.
         You may need to recompile the code.
         (http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedprogramclassmember)
:vet:proguardInternalRelease FAILED
Error:Execution failed for task ':vet:proguardInternalRelease'.
> java.io.IOException: Please correct the above warnings first.

最佳答案

这些是令人讨厌的清理。更好的库现在将它们的设置包含在库包中,但旧的(或更懒惰的)仍然没有。这是我遵循的过程:

开发时:

  • 每当包含新库时,请务必查看其文档以了解其建议的 ProGuard 设置。 (如果您对此很勤奋,则可以避免很多困惑和以后的挖掘。)
  • 如果库作者提供了一个 AAR 包(例如,将“@aar”添加到 gradle 依赖行的末尾以获得完整的 AAR 而不是更简单的 JAR),他们甚至可能在其中为您包含了必要的 ProGuard 异常,这将自动被捡起来。 (但根据我的经验,大多数作者还没有采取这一额外步骤。)
  • 每当在需要动态自省(introspection)的自定义代码中添加新的命名空间/类时,例如在使用依赖注入(inject)容器或 JSON 解析器时,请确保将 ProGuard 设置为根据它们的包名称来选择它们,或者自己添加一个类时间。

  • 构建并收到错误后:
  • 从所有以前缀 error: 开头的行开始然后 warning: (note: 行不会停止构建)。
  • 检查每行提到的命名空间。查找相关的库(例如 com.newrelic.SomeClass 可能是用于 New Relic 库)。如果找不到,试试谷歌搜索,看看命名空间能不能帮你查到github README或其他可能识别 namespace 包含哪个库的东西。或者,查看 Android Studio > 项目 > 包 > 库 列表(第一次显示需要一段时间)并在那里追踪命名空间。希望源代码可用,并在文件头注释中包含库详细信息。
  • 查找该库的文档。希望它提到了必要的 ProGuard 更改。
  • 重建。

  • 图书馆文档所说的所有更改都在其中,但仍然收到警告:
  • 开始添加-dontwarn线。例如:-dontwarn com.newrelic.** (不要忘记双星号,这样它会忽略该命名空间下的整个树;否则单个星号只会忽略命名空间的直接子级。)
  • 如果你开始使用盲dontwarn声明,你必须测试你编译的应用程序(APK)! 因为现在很有可能它会在你身上崩溃,即使调试(非 ProGuard)版本运行良好。确保测试您使用的所有库,检查 logcat 消息,并确保您使用 dontwarn 盲目跳过的所有代码路径/类!

  • 去他妈的,我的老板说我必须发布这个东西:
  • 禁用 ProGuard :-(

  • 使用 Android Studio 中的项目属性对话框,或编辑您的模块 build.gradle文件并更改 android { buildTypes { release { minifyEnabled true } } }并将其设置为 .

    你不会得到 ProGuard 优化,APK 会更大,而且代码不会被混淆。但是,如果您的老板现在只是需要它,而您没有时间调试,那么禁用它不会是世界末日。

    虽然你真的应该使用 ProGuard。也许是时候和老板谈谈,让开发人员有更多的时间去做我们需要做的无聊的技术事情。

    关于android-studio - 使用 ProGuard 缩小时无法使用 Android Studio 构建 APK,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27687870/

    相关文章:

    android - 我试图重新安装相同的包 apk,它给了我错误无效的 apk 文件如何更新它

    android - 无法使用Gradle 2.0

    java - 如何在 SplashScreen 之后启动另一个 Activity。启动画面在给定的计时器之后崩溃

    android - 无法运行 aapt dump badging - Google Play 商店

    android - java.lang.IllegalStateException : Module adapter 错误

    android - proguard 可以混淆原始文件名吗

    android - Proguard 和 XmlPullParser 的问题

    Android 资源编译失败(非转义字符)- 即使我修复了错误

    Android Studio 模拟器符号未找到 : _pwritev

    android - 将 Android 应用程序从 Beta 推广到生产