Android MultiDex - Вопросы по внутренней работе
Недавно я обнаружил новую функциональность MultiDex от Android для работы с приложениями, имеющими более 65 000 ссылок. Смотрите: https://developer.android.com/tools/building/multidex.html
Может ли кто-нибудь помочь мне понять следующие вопросы:
1) Как плагин сборки Gradle определяет, что поместить в первичный файл dex (classes.dex) по сравнению со вторичными файлами dex? Основываясь на документе, есть определенные вещи, которые должны быть в основном dex, но это не дает никаких примеров. Все ли действия должны быть в основном файле dex?
Цитируемый текст:
Существуют сложные требования относительно того, какие классы необходимы в первичном файле dex при выполнении во время выполнения Dalvik. Обновления инструментария сборки Android обрабатывают требования Android, но возможно, что другие включенные библиотеки имеют дополнительные требования к зависимостям, включая использование самоанализа или вызова методов Java из собственного кода. Некоторые библиотеки нельзя будет использовать до тех пор, пока не будут обновлены инструменты построения multidex, чтобы вы могли указать классы, которые должны быть включены в основной файл dex.
2) При сборке только для Android API уровня 21 (Android L) и выше, в плагине Gradle Build действует другое поведение. Он говорит, что это намного быстрее, потому что он "собирает каждый модуль приложения (включая зависимости) как отдельные файлы dex. Обычно это называется предварительным индексированием". Какое определение для модуля в Android? Это упомянутые здесь модули Java Library, Android Library и приложений Android: http://developer.android.com/sdk/installing/studio-build.html? Дистанционные или локальные двоичные зависимости (например, Jars) считаются отдельными модулями и, таким образом, помещаются в другой файл dex или они включаются в модуль в зависимости от них?
2 ответа
1) Плагин Gradle внутренне использует Proguard для создания двух файлов JAR в intermediates/multi-dex
создать папку. Один из них будет основным dex, остальные будут распределены по dex 2, 3 и т. Д.
collect{variant}MultiDexComponents
Задача отвечает за создание файла сохранения для Proguard, вы можете увидеть этот файл и другие параметры Proguard, используемые в подкаталоге конкретного варианта папки, о которой я упоминал выше. Надеюсь, это будет настраиваться в долгосрочной перспективе.
В настоящее время также имеется ошибка, связанная с тестовыми проектами в 1.0.0-rc1 подключаемого модуля gradle ( https://code.google.com/p/android/issues/detail?id=80741). С некоторыми небольшими изменениями обходной путь, который я разместил там, также может быть использован для добавления ваших собственных записей в список хранения (таким образом, гарантируя, что ваши классы попадут в основной список) прямо сейчас.
2) Модули относятся к модулям с точки зрения Gradle, но это действительно могут быть различные элементы, упомянутые в списке, к которому вы привязаны. Если вы делаете сборку Gradle до леденца из командной строки с --info
в качестве флага вы можете увидеть все файлы dex, передаваемые dx
, (Обратите внимание, что это не должно включать мультидексную сборку или сборку с preDexLibraries = false
).
Что помещается в main-dex?
Есть три последовательных задачи, которые вычисляют, какие классы должны быть упакованы в основной dex:
собрать задачу {вариант}MultiDexComponents
Эта задача записывает имена классов всех компонентов приложения (приложения, действия, службы, получатели, поставщики) в текстовый файл в соответствии с манифестом. То есть, если у вас есть компонент, который не зарегистрирован в манифесте, он не будет помещен в main-dex. Есть и другие не-манифестные классы - например, аннотации. Чтобы увидеть полный список, проверьте задачу CreateManifestKeepList.groovy в источниках плагинов.
Результатом этой задачи является файл manifest_keep.txt.
shrink {вариант}MultiDexComponents задача
Эта задача вызывает ProGuard для создания сжатого фляги только с классами, упомянутыми в файле manifest_keep.txt.
Результатом этой задачи является файл componentClasses.jar.
создать {вариант} задачу MainDexClassList
Эта задача берет файл componentClasses.jar и для каждого класса рассчитывает иерархию прямых ссылок (для получения дополнительной информации см. Реализацию). То есть, если один из ваших классов компонентов имеет поле типа X, этот класс X также будет добавлен в список main-dex.
Результатом этой задачи является maindexlist.txt, который включает в себя список всех классов, которые будут упакованы в основной dex.
Что произойдет, если мой minSdk 21?
Ни одна из вышеперечисленных задач не будет запущена, если ваша версия minSdk - 21 - не требуется вычисление основного списка. Это связано с тем, что в ART все файлы dex конвертируются в один файл.oat во время установки приложения. И поэтому не требуется исправление ClassLoader во время выполнения.