我在生成应用程序的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选项后,无论如何我得到了错误,我无法解决这些警告(这里有一些提示,但不是这些警告...):
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.
Jon Adams.. 7
这些都是令人讨厌的清理工作.现在更好的库包括它们在库包中的设置,但旧的(或更长的)库仍然不是.这是我遵循的流程:
开发时:
每当包含新库时,请务必查看其文档以了解其建议的ProGuard设置.(如果你勤勉于此,它会节省很多混乱并在以后挖掘.)
如果库作者提供了一个AAR包(例如将'@aar'添加到gradle依赖行的末尾以获得完整的AAR而不是更简单的JAR),他们甚至可能在那里包含必要的ProGuard异常.自动获取.(但根据我的经验,大多数作者仍然没有采取额外的步骤.)
每当在需要动态内省的自定义代码中添加新的命名空间/类时,例如在使用依赖注入容器或JSON解析器时,请确保ProGuard设置为根据其包名称选择它们,或者在一个类中添加它们.时间.
构建并获取错误后:
与带有前缀开头的所有线开始error:
,然后warning:
(该note:
行不会停止建设).
检查每行提到的命名空间.查找关联的库(例如com.newrelic.SomeClass
,可能是New Relic库).如果找不到,请尝试使用Google搜索来查看命名空间是否可以帮助您跟踪github README
或其他可能识别命名空间包含哪个库的内容.或者,检查Android Studio>项目>包>库列表(第一次显示需要一段时间)并在那里跟踪命名空间.希望源代码可用,并在文件头注释中包含库详细信息.
查找该库的文档.希望它提到必要的ProGuard更改.
重建.
库文档所说的所有更改都在,但仍会收到警告:
开始添加-dontwarn
行.例如:( -dontwarn com.newrelic.**
不要忘记双星号,因此忽略该命名空间下的整个树;否则单个星号将只忽略命名空间的直接子节点.)
如果您开始使用盲语dontwarn
,则必须测试已编译的应用程序(APK)!因为现在它很可能会崩溃,即使调试(非ProGuard)版本运行正常.确保测试您使用的所有库,检查logcat消息,并确保您运行所有盲目跳过的代码路径/类dontwarn
!
搞砸了,我的老板说我必须释放这个东西:
禁用ProGuard :-(
在Android Studio中使用项目属性对话框,或编辑模块build.gradle
文件并更改android { buildTypes { release { minifyEnabled true } } }
并将其设置为false.
您不会获得ProGuard优化,APK会更大,代码也不会被混淆.但是如果你的老板现在只需要它并且你没有时间进行调试,那么禁用它就不会是世界末日.
虽然你真的应该使用ProGuard.或许是时候与老板讨论让开发人员有更多时间来做我们需要的无聊技术.
这些都是令人讨厌的清理工作.现在更好的库包括它们在库包中的设置,但旧的(或更长的)库仍然不是.这是我遵循的流程:
开发时:
每当包含新库时,请务必查看其文档以了解其建议的ProGuard设置.(如果你勤勉于此,它会节省很多混乱并在以后挖掘.)
如果库作者提供了一个AAR包(例如将'@aar'添加到gradle依赖行的末尾以获得完整的AAR而不是更简单的JAR),他们甚至可能在那里包含必要的ProGuard异常.自动获取.(但根据我的经验,大多数作者仍然没有采取额外的步骤.)
每当在需要动态内省的自定义代码中添加新的命名空间/类时,例如在使用依赖注入容器或JSON解析器时,请确保ProGuard设置为根据其包名称选择它们,或者在一个类中添加它们.时间.
构建并获取错误后:
与带有前缀开头的所有线开始error:
,然后warning:
(该note:
行不会停止建设).
检查每行提到的命名空间.查找关联的库(例如com.newrelic.SomeClass
,可能是New Relic库).如果找不到,请尝试使用Google搜索来查看命名空间是否可以帮助您跟踪github README
或其他可能识别命名空间包含哪个库的内容.或者,检查Android Studio>项目>包>库列表(第一次显示需要一段时间)并在那里跟踪命名空间.希望源代码可用,并在文件头注释中包含库详细信息.
查找该库的文档.希望它提到必要的ProGuard更改.
重建.
库文档所说的所有更改都在,但仍会收到警告:
开始添加-dontwarn
行.例如:( -dontwarn com.newrelic.**
不要忘记双星号,因此忽略该命名空间下的整个树;否则单个星号将只忽略命名空间的直接子节点.)
如果您开始使用盲语dontwarn
,则必须测试已编译的应用程序(APK)!因为现在它很可能会崩溃,即使调试(非ProGuard)版本运行正常.确保测试您使用的所有库,检查logcat消息,并确保您运行所有盲目跳过的代码路径/类dontwarn
!
搞砸了,我的老板说我必须释放这个东西:
禁用ProGuard :-(
在Android Studio中使用项目属性对话框,或编辑模块build.gradle
文件并更改android { buildTypes { release { minifyEnabled true } } }
并将其设置为false.
您不会获得ProGuard优化,APK会更大,代码也不会被混淆.但是如果你的老板现在只需要它并且你没有时间进行调试,那么禁用它就不会是世界末日.
虽然你真的应该使用ProGuard.或许是时候与老板讨论让开发人员有更多时间来做我们需要的无聊技术.