minifyEnabled в приложении для Android прерывает вызовы GoogleApi [дубликат]

Dec 16 2020

TL; DR - приложение Android имеет проблемы с Google API, когда minifyEnabled имеет значение true.

Существует приложение для Android, которое использует Google API для создания мероприятий и встреч Google. Я использую довольно стандартные инструменты для работы с этим API , - GoogleAuthorizationCodeFlow, com.google.api.services.calendar.Calendar, com.google.api.services.calendar.model.Event. Я использую способ авторизации «Приложения веб-сервера» вместо «Установленные приложения» без всякой веской причины, но потому, что первое из них уже заработало. В моем режиме отладки все работает нормально, но когда я перехожу в режим выпуска, возникают проблемы.

  • GoogleClientSecretsстановится неспособным обрабатывать secretts.json, console.developers.google.comпредоставленные мне. Тот же файл отлично работает в режиме отладки, но теперь GoogleClientSecrets.getDetailsвозвращает значение null. Забавный факт - GoogleClientSecrets.toString/GoogleClientSecrets.toPrettyStringпоказывать данные из файла, но кажется, что в конфигурационном файле отсутствуют все цитаты. В конечном итоге это исправлено (теперь я создаю секреты напрямую, используя clientId / clientSecret, без файла json), но почему проблема появляется на первом месте?
  • после этого исправления flow.newAuthorizationUrl().setRedirectUri(redirectUrl).build()дает мне https://accounts.google.com/o/oauth2/authвместо https://accounts.google.com/o/oauth2/auth?access_type=offline&approval_prompt=force&client_id=<myClientId>&redirect_uri=<myRedirect>&response_type=code&scope=https://www.googleapis.com/auth/calendar. Большая часть «относительной» части пропускается, хотя redirectUrl и clientId читаются и сохраняются правильно, но в Url их нет. Это было исправлено добавлением -keep class com.google.api.client.googleapis.auth.oauth2.*в мой proguard-rules.pro. Это уже выглядит скорее как обходной путь, чем реальное решение, но позже все станет хуже.
  • после этого исправления, когда я это сделаю
    Credential credential = getCredential(context);
    Calendar service = new Calendar.Builder(HTTP_TRANSPORT,
                            JSON_FACTORY,
                            credential)
                            .setApplicationName(APPLICATION_NAME)
                            .build();
    service.events().insert(calendarId, event)
                            .setConferenceDataVersion(1)
                            .setSupportsAttachments(true)
                            .execute();

с совершенно хорошим событием, которое отлично работает без минификации, тогда я получаю

c.f.b.a.b.c.b: 404 Not Found
{
   "errors" : [ {
     "domain" : "global",
     "reason" : "notFound",
     "message" : "Not Found"
   } ],
   "code" : 404,
   "message" : "Not Found"
}

Это можно исправить -keep class com.google.api.services.calendar.* { *; }в моемproguard-rules.pro

  • после этого исправления та же попытка вставить событие дает мне
    W/System.err: java.lang.IllegalArgumentException: key creator
            at com.google.api.client.json.JsonParser.parseValue(JsonParser.java:889)
            at com.google.api.client.json.JsonParser.parse(JsonParser.java:382)
            at com.google.api.client.json.JsonParser.parse(JsonParser.java:355)
            at com.google.api.client.json.JsonObjectParser.parseAndClose(JsonObjectParser.java:87)
            at com.google.api.client.json.JsonObjectParser.parseAndClose(JsonObjectParser.java:81)
            at com.google.api.client.http.HttpResponse.parseAs(HttpResponse.java:459)
            at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)

После некоторых тестов я заметил, что все вышеперечисленное появляется только тогда, когда minifyEnabled истинно. С minifyEnabled false все работает как шарм. Пока я нашел 3 решения

  • minifyEnabled false. Мне нравятся мои файлы, уменьшенные в выпуске, хотя
  • dontobfuscateи dontshrinkв proguard-rules.pro. Помогает, но снижает эффект минификации.
  • keep class * { *; }в proguard-rules.pro. Помогает, но снижает эффект минификации.

Я не могу поверить, что стандартный вариант, такой как minifyEnabled, сломал бы что-то вроде GoogleAuthorizationстандартных инструментов в com.google.api.client.*таком большом масштабе. Однако я могу поверить в то, что совершаю несколько глупых и очевидных ошибок. Моя последняя капля на данный момент - это путь «Установлено» из «Приложения веб-сервера», но я не возлагаю на это больших надежд - если бы это был основной источник проблем, почему бы он работал без минификации ...

Почему может произойти описанное поведение? Что я делаю не так?

Ответы

IvanGarza Dec 16 2020 at 00:22

Не редкость добавлять исключения правил в ваш proguard-rules.proфайл всякий раз, когда вы обнаруживаете проблемы с запутыванием в сборке релиза.

Сама по себе работа с ProGuard - это целая тема, но не думайте, что добавление исключений к инструменту обфускации вашего приложения подрывает безопасность вашего приложения или еще много чего. Некоторым API и шаблонам кодирования для правильной работы просто требуется несколько исключений; например, классы / модели данных, и все, что поступает из уровня JNI, всегда требует деобфускации.

Вот небольшая статья по этой теме, если вы все еще не уверены.