proguard 导致谷歌播放服务的 ActivityRecognitionResult getMostProbableActivity 崩溃

Posted

技术标签:

【中文标题】proguard 导致谷歌播放服务的 ActivityRecognitionResult getMostProbableActivity 崩溃【英文标题】:proguard causes a crash in google play services' ActivityRecognitionResult getMostProbableActivity 【发布时间】:2013-09-07 17:56:31 【问题描述】:

我最近向 Play 商店发布了一个应用程序,虽然它在没有 proguard 的情况下运行良好,但当我决定使用它时却发生了意外崩溃。

我查看了here 以获取推荐的 google play 服务的 proguard 规则,我还尝试为这种情况添加另一行。这是我得到的(第三行是我的应用程序):

-keep class * extends java.util.ListResourceBundle 
    protected Object[][] getContents();

-keep class * implements com.google.android.gms.internal.ae
-keep class * extends il.co.kix.minitasker.EntityBase

这是执行回溯后的崩溃报告

android.os.BadParcelableException: Parcelable protocol requires a Parcelable.Creator object called CREATOR on class com.google.android.gms.location.ActivityRecognitionResult
at android.os.Parcel.readParcelable(Parcel.java:2086)
at android.os.Parcel.readValue(Parcel.java:1965)
at android.os.Parcel.readMapInternal(Parcel.java:2226)
at android.os.Bundle.unparcel(Bundle.java:223)
at android.os.Bundle.containsKey(Bundle.java:271)
at android.content.Intent.hasExtra(Intent.java:4116)
at com.google.android.gms.location.ActivityRecognitionResult.boolean hasResult(android.content.Intent)(Unknown Source)
                                                             com.google.android.gms.location.DetectedActivity getMostProbableActivity()
at il.co.kix.minitasker.ActivityRecognitionIntentService.void onHandleIntent(android.content.Intent)(Unknown Source)
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.os.HandlerThread.run(HandlerThread.java:60)

有问题的代码行可能是:

...
   @Override
    protected void onHandleIntent(Intent intent) 
        if (ActivityRecognitionResult.hasResult(intent)) 
            ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent);
            DetectedActivity mostProbableActivity = result.getMostProbableActivity();
...

谁能帮忙添加一条规则?我不想一起禁用它,但它确实解决了这个问题。

【问题讨论】:

正如 google 宣布的那样,任何在 google paly 上上传的 apk 现在 google 在 apk 本身上运行 proguard,所以现在不需要在我们这边使用 proguard。 文件大小似乎有非常明显的差异,使用 proguard 时为 800kb,未使用时为 1.2mb。 也许我遗漏了一些东西,但他们真的可以在没有我之后签署代码的情况下做到吗? 与***.com/questions/16362726/… 相同的问题,但没有答案。 @BirajZalavadia 我在谷歌搜索你所说的信息,但我没有得到任何关于你所说的新闻的链接。您能否给我一个链接,您可以在其中看到 Google 将在 apk 本身上运行 proguard 吗? 【参考方案1】:

Android 运行时通过反射的方式访问这些 CREATOR 字段,使用静态分析通常无法检测到。因此,您需要告诉 ProGuard 保留它们:

-keepclassmembers class * implements android.os.Parcelable 
    static ** CREATOR;

这似乎不是android-sdk/tools/proguard/proguard-android.txt 中的标准设置,但应该是。

【讨论】:

【参考方案2】:

这个问题把我逼疯了。 Proguard 正在剥离未显式导入的内部类。更糟糕的是,这个问题对我来说并不存在(在使用 Proguard 之后)然后有一天在一些小的代码更改后突然出现。

我添加了一系列 Proguard 标志来解决这个问题。最后,我不确定是哪一个成功了:

一定要加上这三个:

-keep class android.os.Parcelable.Creator
-keep class com.google.android.gms.location.ActivityRecognitionResult
-keep class com.google.android.gms.** *;

你也可以试试:

-dontshrink
-dontoptimize

在顶部

老实说,这是一个依赖行者类型的问题,Proguard 应该比这更好,但我最终还是按照上面的方法修复了它。

【讨论】:

以上是关于proguard 导致谷歌播放服务的 ActivityRecognitionResult getMostProbableActivity 崩溃的主要内容,如果未能解决你的问题,请参考以下文章

添加播放服务后无法创建发布版本(使用 proguard)

自动上传 ProGuard 映射文件到游戏控制台

Google Play 服务和 Firebase 的 ProGuard 问题

在启用 Proguard 的情况下将 Play 服务从 8.1 更新到 8.3

Proguard NoClassDefFoundError

ProGuard 导致应用滞后