Настройки оптимизации Proguard: включение слияния классов, трансляции и поля / * в современных API и версиях Proguard

Я давно запутал свои приложения, со следующими настройками, которые я принимал как мантры, потому что они были рекомендациями Google

-optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/* 

Однако на днях я прокомментировал эту строку по ошибке, приложение построено правильно, и «очевидно» работает. Я провел много тестов и не смог сбить его с ног.

Поэтому мне интересно, нужны ли отключенные настройки оптимизации …

  • На сегодняшний день Android SDK и новейшие версии Proguard я только нацеливаю устройства с Android 4.0.3 и выше (15) и пользуюсь Proguard 5.1.
  • И для приложений, которые не занимаются экзотическим материалом, и имеют надлежащим образом написанные proguard.cfg инструктирующие держать соответствующие проблемные классы и т. Д.

Большинство ответов, приведенных в этом выпуске, имеют противоречивую информацию и связаны с довольно старыми версиями API.

По одному:

! Код / упрощение / арифметика

Я нашел дискуссию в Google Groups, где говорится, что simplification/arithmethic не требуется для SDK после Android Donut. Я предполагаю, что я могу безопасно включить эту оптимизацию.

Класс! / Сращивание / *

Похоже, proguard неплохо работает в моих проектах с включенной оптимизацией:

 [proguard] Number of vertically merged classes: 296 [proguard] Number of horizontally merged classes: 445 

Существуют ли другие побочные эффекты, кроме следов стека? Я имею в виду, что побочные эффекты, связанные с сбоем приложения, а не отладки проблем. Я нашел этот связанный вопрос, но он не считает, что это безопасно или нет.

! Поле / * и! Код / упрощение / литье

Я прочитал в этом вопросе автор ProGuard, что они были включены, чтобы избежать ошибок со старыми версиями Proguard. Так безопасно ли их активировать на Proguard 5.1?

Общий совет: нет никакой гарантии, что оптимизация не будет работать, но всегда есть риск . То, что настройки Android proguard по умолчанию пытаются сделать, это предоставить конфигурацию, которая минимизирует этот риск, поэтому почему они выглядят настолько консервативными для вашей конкретной ситуации.

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

Таким образом, если вы можете запустить APK, и все это работает – тогда отлично, оптимизация работает для вас. Но они не гарантированы.

Так безопасно ли их активировать на Proguard [5.1]?

Это шаг с высоким риском, и я могу привести пример, где это вызывает проблему.

Мы используем ProGuard 5.2.1, и мы сталкиваемся с ошибкой при повторной настройке оптимизации field/* (точнее, проблема с field/removal/writeonly ). В нашем коде используется protobuf и эта оптимизация заставляет ProGuard терпеть неудачу с этим сообщением на третьем проходе оптимизаций:

 Оптимизация ...
  Неожиданные ошибки при оценке инструкции:
   Class = [com / google / protobuf / FieldSet $ ​​1]
   Метод = [() V]
   Инструкция = [308] isub
   Exception = [java.lang.IllegalArgumentException] (Значение «com / google / protobuf / WireFormat $ JavaType!» Не является целым значением [proguard.evaluation.value.TypedReferenceValue])
 Неожиданная ошибка при частичной оценке:
   Class = [com / google / protobuf / FieldSet $ ​​1]
   Метод = [() V]
   Exception = [java.lang.IllegalArgumentException] (Значение «com / google / protobuf / WireFormat $ JavaType!» Не является целым значением [proguard.evaluation.value.TypedReferenceValue])
 Предупреждение: исключение во время обработки java.io.IOException: java.lang.IllegalArgumentException: значение «com / google / protobuf / WireFormat $ JavaType!»  Не является целым значением [proguard.evaluation.value.TypedReferenceValue]

Это означает, что тот факт, что эти оптимизации были отключены на протяжении стольких лет, означает, что они, вероятно, не так хорошо поддерживаются, как другие. К счастью, это было поймано во время компиляции, но повторное включение некоторых из этих оптимизаций (например, горизонтальное слияние классов с помощью class/merging/* ) может легко разбить ваше приложение в определенных версиях / сборках Android, не сообщая должным образом вам «разработчик», (Например, это может привести к сбою dexopts или вообще не установить с помощью VerifyError ).

Intereting Posts
Android – Найти ориентацию фотографии взяла камера Java.lang.NoClassDefFoundError: org.apache.http.params.SyncBasicHttpParams Добавить подкласс InputMethodService Как увеличить выбранную высоту вкладки в виджетах вкладки? Повторное использование Google Map v2 для нескольких фрагментов в одной активности Как мы создаем мобильное родное приложение, чтобы мы могли использовать его как для Android, так и для WP7? Токен доступа удален в Android Android SDK 4.0 Понимание сбоев и ANR с защитой Proguard Android AutoCompleteTextView предлагает альтернативу Android onPreviewFrame не вызывается Показать ImageView частично за прозрачным ActionBar Использование локального устройства ADB на устройстве (loopback) показывает отсутствие устройств Как преобразовать массив байтов в Bitmap Как указать количество элементов списка в предварительном просмотре recyclerview в Android Studio? Почему GSON ставит десятичную точку и нуль после всех моих номеров JSON, которые изначально не содержат десятичных чисел?