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 服务库而失败

使用 Proguard 删除 Google Play Services 库中未使用的类

Google Play Services v23 Proguard 配置

Google Play 服务和 Firebase 的 ProGuard 问题

Google Play Service 的 proguard 配置,在我的应用程序中还是在 lib 项目中?