TL; ДР: инвертируйте свой вариант -keep
, если вы любите неприятности
Во-первых: я считаю, что вы делаете правильный выбор, используя Proguard для преодоления ограничения dex. Я бы не рекомендовал использовать библиотеку поддержки multidex ни при каких обстоятельствах: это создает проблему нескольких загрузчиков классов в вашем приложении, и это может иметь неприятные последствия многими неочевидными способами.
Вот мой личный подход к эффективному сжатию приложения:
- Выберите пару самых больших сторонних зависимостей, которые у вас есть;
- Проверьте, действительно ли они поддерживают Proguard;
- Если да, уменьшите их с помощью Proguard;
- Если вы все еще не вписываетесь в максимальное количество методов, выполните шаги, описанные выше, для некоторых оставшихся зависимостей;
- Если вы все еще не подходите, возможно, переоцените некоторые из них, которые не поддерживают Proguard, возможно, прочитайте их исходный код, чтобы лучше понять, почему они не поддерживают, и примените Proguard. к ним себя;
- В худшем случае примените Proguard к своему коду;
- Если абсолютно ничего из вышеперечисленного не помогает, используйте multidex.
Выбор зависимостей для сжатия
В вашем случае не так много (прямых) зависимостей. Вы можете просмотреть вывод gradlew dependencies
, чтобы получить более полное представление о ваших непрямых зависимостях, некоторые из которых могут вносить наибольший вклад в общий размер приложения. Затем вы можете продолжить использовать некоторые из инструментов, перечисленных в разделе «Dex» Android Arsenal, чтобы узнать, какие библиотеки больше всего способствуют подсчету методов dex. Вы, кажется, уже имеете общее представление об этом, так что я не буду долго останавливаться на этой части.
Помните: сжатие исполняемого кода — это несколько нетривиальное вмешательство во внутренние процессы библиотеки, так что лучше сжимать меньше, чтобы избежать загадочных проблем в будущем. Если вы сомневаетесь, начните с библиотек, которые открыто заявляют, что они действительно официально поддерживают Proguard (в вашем случае это будут библиотеки поддержки Android).
Обратите внимание, что «поддержка Proguard» может означать разные вещи для разных разработчиков. Вы можете ожидать, что разработчики библиотеки поддержки Android будут, по крайней мере, в основном компетентными, но многие другие будут поставляться с потребительскими правилами Proguard, такими как это:
-keep class com.example.library.** { *; }
Если вам интересно, приведенная выше конфигурация основана на многих реальных конфигурациях, таких как Конфигурация Square's Leak Canary Proguard. В нем ничего не говорится об общей компетенции рассматриваемых разработчиков, просто напоминание о том, что использование Proguard может быть трудным. И да, такая конфигурация полностью предотвратит сжатие и запутывание библиотеки, если только вы не соберете ее локальную копию из исходного кода и не удалите оттуда такие полезные consumer-proguard-rules.pro
.
Оценка зависимостей для Proguard
Как показано выше, даже опытные разработчики иногда игнорируют Proguard. Если поиск в Google относительно библиотеки и ее совместимости с Proguard ничего не возвращает (и даже если они делают какие-то результаты!), вам, возможно, придется принять собственное решение относительно использования Proguard. Вот как я лично делаю:
- Если где-то на сайте библиотеки есть слова "framework", "enterprise", "reflection", скорее всего, она плохо совместима с Proguard;
- Если библиотека имеет какое-либо отношение к генерации кода во время компиляции (например, Butterknife, Dagger и т. д.), подумайте дважды, прежде чем использовать Proguard;
- Если библиотека путается с JNI, подумайте еще пару раз, прежде чем использовать для нее Proguard, и погуглите, чтобы узнать о ее влиянии на Proguard, даже если вы не сжимаете саму библиотеку;
- Если вы сомневаетесь, погуглите и/или прочитайте исходный код библиотеки: использование
Class.forName
, а также Proxy.getInvocationHandler
и подобного кода отражения обычно является плохим признаком.
Библиотеки, которые предлагают компоненты пользовательского интерфейса Android (например, MPAndroidChart), обычно можно уменьшить, по крайней мере, если вы сохраните getDefaultProguardFile('proguard-android.txt')
в своей конфигурации Gradle.
Самая важная часть
Многие разработчики (включая самих разработчиков Proguard!) предложат вам ошибочную рекомендацию начать с пустой конфигурации Proguard + конфигурации Android Proguard по умолчанию и в конечном итоге добавить -keep
правил, когда это необходимо.
НЕ ДЕЛАЙТЕ ЭТОГО!!
Эти советы исходят от людей, которые либо слишком круты, чтобы понять проблемы среднего разработчика (читай: «сам разработчик Proguard»), либо не имеют ни малейшего представления о том, как правильно использовать Proguard. На самом деле, подобные ошибочные действия являются той самой причиной, по которой многие ответы на этот вопрос предостерегают вас от использования Proguard: его поведение по умолчанию похоже на предложение кому-то начать альпинизм с восхождения на Эверест.
Конфигурация Proguard по умолчанию запутывает, сжимает и оптимизирует все — все ваше приложение со всеми зависимостями, кроме некоторых классов, которые вы явно исключили. Вы не хотите этого, если у вас нет абсолютного понимания каждой библиотеки и строки кода в ваших проектах: как они работают и взаимодействуют друг с другом, какие методы они используют внутри и т. д.
Вместо этого вы хотите сделать минимально необходимое вмешательство (уменьшить код, чтобы уменьшить количество методов dex) в минимально возможном диапазоне (несколько самых больших библиотек) с минимальными последствиями (только там, где точно известно, что Proguard работает). Вот мой конфиг Proguard для таких случаев:
-dontoptimize
-dontobfuscate
# Prints some helpful hints, always add this option
-verbose
-keepattributes SourceFile,LineNumberTable,Exceptions,InnerClasses,Signature,Deprecated,*Annotation*,EnclosingMethod
# add all known-to-be-safely-shrinkable classes to the beginning of line below
-keep class !com.android.support.**,!com.google.android.**,** { *; }
Добавьте приведенные выше правила в proguard-rules.pro
вашего приложения, они будут сокращать только те классы, которые вы явно разрешаете сокращать. Добавьте подстановочные знаки для других безопасно сжимаемых пакетов (точно так же, как указано выше — с частями !
и .**
) в начало строки -keep
.
person
user1643723
schedule
20.07.2015
im reaching the 65k Methode Limit
. Пожалуйста, опубликуйте свойbuild.gradle
. - person Jared Burrows   schedule 20.07.2015