如何让 R8 + proguard-android-optimize.txt + Google Drive API 无缝运行?

Posted

技术标签:

【中文标题】如何让 R8 + proguard-android-optimize.txt + Google Drive API 无缝运行?【英文标题】:How to make R8 + proguard-android-optimize.txt + Google Drive API works seamlessly? 【发布时间】:2019-11-24 04:25:55 【问题描述】:

这是我们的 R8 版本

当前版本是:1.4.94(来自 go/r8bot (luci-r8-ci-archive-0-5g74) 的构建 390954928f0db9c3b888a367f7f128ce3bbfb160)。

当我切换时

buildTypes 
    release 
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    

buildTypes 
    release 
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    

我们收到以下错误。

com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden
    
      "code": 403,
      "errors": [
        
          "domain": "usageLimits",
          "message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup.",
          "reason": "dailyLimitExceededUnreg",
          "extendedHelp": "https://code.google.com/apis/console"
        
      ],
      "message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup."
    
        at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:113)
        at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:40)
        at com.google.api.client.googleapis.services.AbstractGoogleClientRequest$1.interceptResponse(AbstractGoogleClientRequest.java:378)
        at com.google.api.client.http.HttpRequest.a(HttpRequest.java:1067)
        at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:476)
        at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:409)
        at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:526)
        at com.yocto.wenote.sync.Utils.searchFromGoogleDrive(Utils.java:808)

崩溃发生在以下代码中

try 
    Drive.Files.List request = drive.files().list().setSpaces(APP_DATA_FOLDER)
            .setQ("name = '" + Utils.getWeNoteZipFileTitle() + "'")
            .setFields("nextPageToken, files(id, name, modifiedTime)")
            .setOrderBy("modifiedTime desc")
            .setPageSize(10);

    do 
        FileList fileList = request.execute();  // <-- This is line Utils.java:808

请注意,在我们从 proguard-android.txt 切换到 proguard-android-optimize.txt 之前,上述代码可以 100% 正常运行。

看来R8基于proguard-android-optimize.txt,将一些重要信息条带化,导致调用Google Drive API失败。

任何人如何使proguard-android-optimize.txt 与 Google Drive API 一起工作?


用 Proguard 替换 R8 怎么样?

如果我通过应用android.enableR8=false(仍然使用proguard-android-optimize.txt)使用ProGuard 6.0.3 版,运行Google Drive API 相关代码时没有问题。


我的 Google Drive API 库

// For Google Drive REST API - https://github.com/gsuitedevs/android-samples/blob/master/drive/deprecation/app/build.gradle
implementation('com.google.http-client:google-http-client-gson:1.26.0') 
    exclude group: 'org.apache.httpcomponents'

implementation('com.google.api-client:google-api-client-android:1.26.0') 
    exclude group: 'org.apache.httpcomponents'

implementation('com.google.apis:google-api-services-drive:v3-rev136-1.25.0') 
    exclude group: 'org.apache.httpcomponents'

我完整的 proguard 文件

-keep class * implements android.os.Parcelable 
*;




# https://github.com/huanghaibin-dev/CalendarView
-keep class com.yocto.wenote.calendar.CustomWeekView 
    public <init>(android.content.Context);

-keep class com.yocto.wenote.calendar.CustomMonthView 
    public <init>(android.content.Context);

-keep class com.yocto.wenote.calendar.CustomWeekBar 
    public <init>(android.content.Context);

-keep class com.yocto.wenote.calendar.FullscreenCustomWeekBar 
    public <init>(android.content.Context);

-keep class com.haibin.calendarview.DefaultWeekView 
    public <init>(android.content.Context);

-keep class com.haibin.calendarview.DefaultYearView 
    public <init>(android.content.Context);


# http://***.com/questions/3913338/how-to-debug-with-obfuscated-with-proguard-applications-on-android
# http://proguard.sourceforge.net/index.html#manual/examples.html (Producing useful obfuscated stack traces)
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable,InnerClasses



# https://github.com/bumptech/glide
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public class * extends com.bumptech.glide.module.AppGlideModule
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** 
  **[] $VALUES;
  public *;




# Used in menu/search_toolbar_menu.xml
-keep class com.yocto.wenote.search.SearchView 
*;




# setHintTextTypeface & setFloatTextTypeface & setFloatTextColor
-keep class com.google.android.material.textfield.TextInputLayout 
*;

# setHintTextTypeface & setFloatTextTypeface
-keep class com.google.android.material.internal.CollapsingTextHelper 
*;

# setMaxHeight & setMinimumHeight
-keep class android.widget.ImageView 
  public <methods>;




-keep class com.yocto.wenote.recording.RippleBackground$RippleView 
  void setScaleX(***);
  void setScaleY(***);




# https://github.com/zhihu/Matisse
-dontwarn com.squareup.picasso.**
-dontwarn com.bumptech.glide.**



# For Google Drive API
-dontwarn com.google.common.**
-dontwarn com.google.api.client.util.**
-keep class * extends com.google.api.client.json.GenericJson 
*;

-keep class com.google.api.services.drive.** 
*;



# VerifyError in Android 4
# https://github.com/material-components/material-components-android/issues/397
-keep class com.google.android.material.tabs.TabLayout$Tab 
*;



# http://developer.android.com/google/play/billing/billing_best_practices.html#obfuscate
-keep class com.android.vending.billing.**



# https://r8.googlesource.com/r8/+/refs/heads/master/compatibility-faq.md
-keepclassmembers,allowobfuscation class * 
  @com.google.gson.annotations.SerializedName <fields>;




# https://***.com/questions/13218772/removing-log-call-using-proguard
-assumenosideeffects class android.util.Log 
    public static boolean isLoggable(java.lang.String, int);
    public static int v(...);
    public static int i(...);
    public static int w(...);
    public static int d(...);
    public static int e(...);




# https://***.com/questions/13218772/removing-log-call-using-proguard
-assumenosideeffects class com.yocto.wenote.Utils 
    public static void trackView(...);
    public static void trackEvent(...);

【问题讨论】:

【参考方案1】:

你能试试下面的保持规则吗?

-keepclassmembers class * 
  @com.google.api.client.util.Key <fields>;

google api 客户端通过反射使用 com.google.api.client.util.Key: https://developers.google.com/api-client-library/java/google-http-java-client/setup

这似乎适用于报告类似问题的其他人。

【讨论】:

这对我也有用!我正在使用 minify,然后每次尝试在 google drive 上打开文件夹时都会出现此错误。很高兴它解决了。 MortenKJ - 它工作正常,正是需要的,很棒的发现。读者请避免使用更广泛的解决方案,因为其他一些人建议使用 -keep class com.google.** *;,因为它会降低效率并且不会缩小或混淆许多谷歌包,使用这种类型的有限方法来只保留绝对必要的类/成员。

以上是关于如何让 R8 + proguard-android-optimize.txt + Google Drive API 无缝运行?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用最新的 R8 Shrinker 版本

Android/Java 混淆:R8 与(ProGuard 或 DexGuard)?

如何修复因 ProGuard/R8 导致的崩溃?

Android build.gradle 中的 proguard-android-optimize.txt 与 proguard-android.txt

如何将 NDK 降级到 r8e

脱糖与DXD8R8