Proguard 使用 Google Play 服务库返回错误
Posted
技术标签:
【中文标题】Proguard 使用 Google Play 服务库返回错误【英文标题】:Proguard returned error with Google Play Services library 【发布时间】:2014-08-11 17:29:00 【问题描述】:我将 Google Play 服务库添加到我的应用程序中。一切正常,但我的 apk 大小从 350KB 增加到 1.6MB,增加了 4 倍(!)。为了从 Google Play Services 库中删除未使用的类,我决定使用 ProGuard。但现在我无法运行项目或将其导出到 apk,因为 ProGuard 返回错误。当我不使用 GPS 库时,导出没有问题,但我无法使用该库创建 apk。 我阅读了很多关于这个问题的信息,但我找到的任何解决方案都对我没有帮助。
这是我的 proguard-project.txt(推荐 here)
-keep class * extends java.util.ListResourceBundle
protected Object[][] getContents();
-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable
public static final *** NULL;
-keepnames @com.google.android.gms.common.annotation.KeepName class *
-keepclassmembernames class *
@com.google.android.gms.common.annotation.KeepName *;
-keepnames class * implements android.os.Parcelable
public static final ** CREATOR;
这是我的 proguard.cng
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
#keep all classes that might be used in XML layouts
-keep public class * extends android.view.View
-keep public class * extends android.app.Fragment
-keep public class * extends android.support.v4.Fragment
#keep all public and protected methods that could be used by java reflection
-keepclassmembernames class *
public protected <methods>;
-keepclasseswithmembernames class *
native <methods>;
-keepclasseswithmembernames class *
public <init>(android.content.Context, android.util.AttributeSet);
-keepclasseswithmembernames class *
public <init>(android.content.Context, android.util.AttributeSet, int);
-keepclassmembers enum *
public static **[] values();
public static ** valueOf(java.lang.String);
-keep class * implements android.os.Parcelable
public static final android.os.Parcelable$Creator *;
-dontwarn **CompatHoneycomb
-dontwarn org.htmlcleaner.*
-dontwarn com.google.android.gms.**
-keep class com.google.android.gms.common.GooglePlayServicesUtil *;
-keep class com.google.ads.** *;
这里是我导出到 apk 后得到的一个错误:
[2014-06-20 23:11:38 - Dictionary] Proguard returned with error code 1. See console
[2014-06-20 23:11:38 - Dictionary] You should check if you need to specify additional program jars.
[2014-06-20 23:11:38 - Dictionary] Unexpected error while performing partial evaluation:
[2014-06-20 23:11:38 - Dictionary] Class = [com/google/android/gms/common/GooglePlayServicesUtil]
[2014-06-20 23:11:38 - Dictionary] Method = [showErrorDialogFragment(ILandroid/app/Activity;ILandroid/content/DialogInterface$OnCancelListener;)Z]
[2014-06-20 23:11:38 - Dictionary] Exception = [java.lang.IllegalArgumentException] (Can't find any super classes of [com/google/android/gms/common/SupportErrorDialogFragment] (not even immediate super class [android/support/v4/app/DialogFragment]))
[2014-06-20 23:11:38 - Dictionary] java.lang.IllegalArgumentException: Can't find any super classes of [com/google/android/gms/common/SupportErrorDialogFragment] (not even immediate super class [android/support/v4/app/DialogFragment])
[2014-06-20 23:11:38 - Dictionary] at proguard.evaluation.value.ReferenceValue.generalize(ReferenceValue.java:299)
[2014-06-20 23:11:38 - Dictionary] at proguard.evaluation.value.IdentifiedReferenceValue.generalize(IdentifiedReferenceValue.java:65)
[2014-06-20 23:11:38 - Dictionary] at proguard.evaluation.value.ReferenceValue.generalize(ReferenceValue.java:481)
[2014-06-20 23:11:38 - Dictionary] at proguard.evaluation.Variables.generalize(Variables.java:136)
[2014-06-20 23:11:38 - Dictionary] at proguard.evaluation.TracedVariables.generalize(TracedVariables.java:118)
[2014-06-20 23:11:38 - Dictionary] at proguard.optimize.evaluation.PartialEvaluator.evaluateSingleInstructionBlock(PartialEvaluator.java:682)
[2014-06-20 23:11:38 - Dictionary] at proguard.optimize.evaluation.PartialEvaluator.evaluateInstructionBlock(PartialEvaluator.java:602)
[2014-06-20 23:11:38 - Dictionary] at proguard.optimize.evaluation.PartialEvaluator.evaluateInstructionBlockAndExceptionHandlers(PartialEvaluator.java:560)
[2014-06-20 23:11:38 - Dictionary] at proguard.optimize.evaluation.PartialEvaluator.visitCodeAttribute0(PartialEvaluator.java:264)
[2014-06-20 23:11:38 - Dictionary] at proguard.optimize.evaluation.PartialEvaluator.visitCodeAttribute(PartialEvaluator.java:181)
[2014-06-20 23:11:38 - Dictionary] at proguard.classfile.attribute.CodeAttribute.accept(CodeAttribute.java:101)
[2014-06-20 23:11:38 - Dictionary] at proguard.classfile.ProgramMethod.attributesAccept(ProgramMethod.java:79)
[2014-06-20 23:11:38 - Dictionary] at proguard.classfile.attribute.visitor.AllAttributeVisitor.visitProgramMember(AllAttributeVisitor.java:95)
[2014-06-20 23:11:38 - Dictionary] at proguard.classfile.util.SimplifiedVisitor.visitProgramMethod(SimplifiedVisitor.java:91)
[2014-06-20 23:11:38 - Dictionary] at proguard.classfile.ProgramMethod.accept(ProgramMethod.java:71)
[2014-06-20 23:11:38 - Dictionary] at proguard.classfile.ProgramClass.methodsAccept(ProgramClass.java:504)
[2014-06-20 23:11:38 - Dictionary] at proguard.classfile.visitor.AllMethodVisitor.visitProgramClass(AllMethodVisitor.java:47)
[2014-06-20 23:11:38 - Dictionary] at proguard.classfile.ProgramClass.accept(ProgramClass.java:346)
[2014-06-20 23:11:38 - Dictionary] at proguard.classfile.ClassPool.classesAccept(ClassPool.java:116)
[2014-06-20 23:11:38 - Dictionary] at proguard.optimize.Optimizer.execute(Optimizer.java:372)
[2014-06-20 23:11:38 - Dictionary] at proguard.ProGuard.optimize(ProGuard.java:306)
[2014-06-20 23:11:38 - Dictionary] at proguard.ProGuard.execute(ProGuard.java:115)
[2014-06-20 23:11:38 - Dictionary] at proguard.ProGuard.main(ProGuard.java:492)
我的本地配置可能有问题...
我尝试了 -keep
和 -dontwarn
不同的课程,但现在没有任何帮助......
请帮帮我!
【问题讨论】:
【参考方案1】:将 android-support-v4.jar 添加到您的项目中
【讨论】:
【参考方案2】:如果您使用 Eclipse ADT:您应该引用您复制到开发工作区的库 Google Play Services 的副本 - 您不应该直接从 Android SDK 目录引用该库。
https://developers.google.com/android/guides/setup
【讨论】:
【参考方案3】:在生成签名版本时,我遇到了类似的问题,而 Prograud 几乎没有其他问题。经过大量搜索,我终于能够解决我的问题。我相信人们有比下面一个更好的解决方案。
-
保留最新的 SDK 和支持的库。
在“/sdk/tools/progaurd/”中创建一个文件夹“libs”。
将应用程序所需的 .jar 文件(例如“android-support-v13.jar”、“google-play-services.jar”)复制到“/sdk/tools/progaurd/libs/”文件夹中。李>
将 .jar 复制到您的应用程序“libs”文件夹中。
同时删除“android-support-v4.jar”,因为它不是必需的,这里 v13 已经支持 v4
将 .jar 文件添加到您的构建路径。
同时从构建路径中删除“android-support-v4.jar”,因为它不是必需的,这里 v13 已经支持 v4。
在您的应用程序 project.properties 文件中添加以下行。请仅将目标保留为“android-22”。
proguard.config=$sdk.dir/tools/proguard/proguard-android.txt # Project target. target=android-22 android.library.reference.1=../../dev/sdk/extras/google/google_play_services/libproject/google-play-services_lib
-
我的 Progaurd 文件“proguard-android.txt”。请根据您的要求进行更改。
-optimizationpasses 2 -dontusemixedcaseclassnames -dontskipnonpubliclibraryclasses -dontskipnonpubliclibraryclassmembers -dontpreverify -dontshrink -verbose -dontwarn org.apache.** -dontwarn org.slf4j.** -dontwarn org.json.* -dontwarn org.mortbay.** -dontwarn org.apache.log4j.** -dontwarn org.apache.commons.logging.** -dontwarn org.apache.commons.logging.** -dontwarn org.apache.commons.codec.binary.** -dontwarn javax.xml.** -dontwarn javax.management.** -dontwarn java.lang.management.** -libraryjars libs/android-support-v13.jar -libraryjars libs/google-play-services.jar -dontwarn android.support.v13.** -keep class android.support.v13.** *; -keep interface android.support.v13.app.** *; -keep public class * extends android.support.v13.** -keep public class * extends android.app.Fragment -dontwarn com.google.android.gms.** -keep class com.google.android.gms.** *; -dontwarn com.google.code.** -dontwarn oauth.signpost.** -dontwarn twitter4j.** -dontwarn com.google.ads.** -dontwarn org.acra.** -optimizations !code/simplification/arithmetic,!field/*,!class/merging/* -allowaccessmodification -keepattributes *Annotation* -renamesourcefileattribute SourceFile -keepattributes SourceFile,LineNumberTable -repackageclasses '' -keep public class * extends android.app.Activity -keep public class * extends android.app.Application -keep public class * extends android.app.Service -keep public class * extends android.content.BroadcastReceiver -keep public class * extends android.content.ContentProvider -keep public class * extends android.app.backup.BackupAgentHelper -keep public class * extends android.preference.Preference -keep public class com.android.vending.licensing.ILicensingService -keep public class com.google.code.linkedinapi.** -keep public class android.content.** *; -keep class javax.** *; -keep class org.** *; -keep class twitter4j.** *; -keep class java.lang.management.** *; -keep class com.google.code.** *; -keep class oauth.signpost.** *; -keep class org.acra.** *; -keepclassmembers public class com.google.code.linkedinapi.client.impl.LinkedInApiXppClient public <init>(java.lang.String, java.lang.String); -keepclasseswithmembernames class * native <methods>; -keepclasseswithmembernames class * public <init>(android.content.Context, android.util.AttributeSet); -keepclasseswithmembernames class * public <init>(android.content.Context, android.util.AttributeSet, int); -keepclassmembers class **.R$* public static <fields>; -keepclassmembers enum * public static **[] values(); public static ** valueOf(java.lang.String); -keep public class * public protected *; -keep class * implements android.os.Parcelable public static final ** CREATOR;
最好的问候, 维克
【讨论】:
【参考方案4】:即使我有 google play 服务作为库,我仍然必须手动将 android-support-v4.jar 添加到我的 libs 文件夹并右键单击并添加到 Eclipse 中的构建路径。
我的 proguard 文件如下所示:
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontwarn com.google.**
-dontpreverify
-dontwarn android.support.v4.**
-dontwarn org.apache.commons.codec.binary.Base64
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-keep class !mycode.** *;
最后一行使它只有我的代码被混淆了。它更清洁。
【讨论】:
以上是关于Proguard 使用 Google Play 服务库返回错误的主要内容,如果未能解决你的问题,请参考以下文章
Android Studio 中带有 Proguard 的 Google Play 服务
使用 Proguard 删除 Google Play Services 库中未使用的类
Google Play Services v23 Proguard 配置