ProGuard: 找不到引用的类 com.google.android.gms.R

72

在Android SDK管理器更新后,我尝试制作签名APK并出现了以下错误:

ProGuard: [] Warning: com.google.android.gms.auth.GoogleAuthUtil: 
  can't find referenced class com.google.android.gms.R
ProGuard: [] Warning: com.google.android.gms.auth.GoogleAuthUtil: 
  can't find referenced class com.google.android.gms.R$string
...
etc.

如果设置了-dontwarn com.google.android.gms.**,编译就能成功。但是在运行时,我收到了很多来自许多设备的错误报告,如下所示:
Caused by: android.view.InflateException: Binary XML file line #32: 
  Error inflating class com.google.android.gms.common.SignInButton

我的设备上一切正常。在更新之前,我没有收到ProGuard警告并且一切都运行得很完美。如何解决这个问题?


可能是proguard hell - can't find referenced class的重复问题。 - Yuliia Ashomok
4个回答

141

虽然将这段代码添加到 proguard-project.txt 文件中可以起作用,但它会保留所有类。

-keep class com.google.android.gms.** { *; }
-dontwarn com.google.android.gms.**

我更喜欢这个选项,可以使apk文件大小更小:

-keep public class com.google.android.gms.* { public *; }
-dontwarn com.google.android.gms.**

请注意最新的Google Play Proguard通知,此处链接:http://developer.android.com/google/play-services/setup.html#Proguard

-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;
}

1
你的第二个建议帮助我节省了几兆字节。谢谢! - palvarez89
10
这还有意义吗?play-services的proguard部分说不需要特殊配置。 - AsafK
我已删除那两行代码,APK 生成顺利,没有任何问题。Firebase 分析和邀请功能正常,其他功能还未尝试。 - Mark
我在Xamarin上仍然不断收到崩溃报告Didn't find class "com.google.android.gms.measurement.AppMeasurementInstallReferrerReceiver" on path DexPathList,所以我将实现这些代码并查看是否适用于我。 - Pierre

42

你需要像编译一样忽略它,但是你也需要保留类,以便在运行时找到它。

将这两行添加到您的Proguard配置文件中:

-keep class com.google.android.gms.** { *; }
-dontwarn com.google.android.gms.**

9
这保留了太多。 - rds
@rds 显然它使用通配符,您可以通过提供更具体的类命名来选择所需内容。当您开始削减 GMS 类时,可能会遇到许多意外的用户崩溃问题。 - Codeversed
我们是否应该在一般情况下使用keep和dontwarn来忽略任何我们想要忽略的警告? - Emil

2

如果您使用proguard,您需要保留一些GMS(Google Play Services)类。希望它们标注有@com.google.android.gms.common.annotation.KeepName

# Proguard config for project using GMS

-keepnames @com.google.android.gms.common.annotation.KeepName class
    com.google.android.gms.**,
    com.google.ads.**

-keepclassmembernames class
    com.google.android.gms.**,
    com.google.ads.** {
    @com.google.android.gms.common.annotation.KeepName *;
}

# Called by introspection
-keep class
    com.google.android.gms.**,
    com.google.ads.**
    extends java.util.ListResourceBundle {
    protected java.lang.Object[][] getContents();
}


# This keeps the class name as well as the creator field, because the
# "safe parcelable" can require them during unmarshalling.
-keepnames class
    com.google.android.gms.**,
    com.google.ads.**
    implements android.os.Parcelable {
    public static final ** CREATOR;
}

# com.google.android.gms.auth.api.signin.SignInApiOptions$Builder
# references these classes but no implementation is provided.
-dontnote com.facebook.Session
-dontnote com.facebook.FacebookSdk
-keepnames class com.facebook.Session {}
-keepnames class com.facebook.FacebookSdk {}

# android.app.Notification.setLatestEventInfo() was removed in
# Marsmallow, but is still referenced (safely)
-dontwarn com.google.android.gms.common.GooglePlayServicesUtil

2

我遇到了一个类似的问题,最终发现我已经更新了Google Play服务模块,但是我没有重新将该模块添加到我的Android Studio主模块中。将其添加回去解决了我的问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接