Что такое .dex-файлы в Android?
У меня есть некоторые вопросы относительно файлов dex
- Что такое файл dex в Android?
- Как работает dex для Android?
- Как они используются при отладке приложения для Android?
- Являются ли они похожими на файлы классов java?
Мне нужна конкретная информация, пожалуйста, помогите в этом, и любые реальные примеры приветствуются!
Скомпилированный файл кода приложения Android.
Программы Android скомпилированы в файлы .dex (Dalvik Executable), которые, в свою очередь, заархивированы в один файл .apk на устройстве. .dex файлы могут быть созданы автоматически Android, путем перевода скомпилированных приложений, написанных на языке программирования Java.
О файле .dex:
Одна из самых замечательных особенностей Dalvik Virtual Machine (рабочая лошадка в системе Android) заключается в том, что она не использует байт-код Java. Вместо этого был введен домашний формат DEX, и даже инструкции байт-кода не совпадают с инструкциями байт-кода Java.
Программы Android скомпилированы в .dex (Dalvik Executable), которые, в свою очередь, заархивированы в один файл .apk на устройстве. .dex файлы могут быть созданы путем автоматического перевода скомпилированных приложений, написанных на языке программирования Java.
Формат файла Dex:
Android имеет документацию по Dalvik Executable Format файлу Dalvik Executable Format (файлы .dex ). Вы можете узнать больше в официальных документах: Dex File Format
.dex файлы похожи на файлы классов java, но они работают под управлением DVM .
Вы можете decompile .dex, используя инструмент dexdump , который предоставляется в android-sdk.
Существуют также некоторые обратные инженерные методы, чтобы сделать jar file или java class file из файла .dex .
Файл dex – это файл, который выполняется на VM Dalvik.
Dalvik VM включает в себя несколько функций для оптимизации производительности, проверки и мониторинга, одним из которых является Dalvik Executable (DEX) .
Исходный код Java скомпилирован компилятором Java в .class . Затем инструмент dx (dexer), входящий в состав Android SDK, обрабатывает .class в формате файлов DEX который содержит байт-код Dalvik. Инструмент dx устраняет всю избыточную информацию, присутствующую в классах. В DEX все классы приложения упаковываются в один файл. В следующей таблице приведено сравнение размеров кода для jar-файлов JVM и файлов, обработанных инструментом dex .
В таблице сравниваются размеры кода для системных библиотек, приложений веб-браузера и приложения общего назначения (приложение для будильника). Во всех случаях инструмент dex уменьшает размер кода более чем на 50%.
В стандартных средах Java каждый класс в Java-коде приводит к одному .class файлу. Это означает, что если файл исходного кода Java имеет один открытый класс и два анонимных класса, скажем, для обработки событий, тогда java-компилятор создаст всего три файла .class .
Шаг сборки такой же на платформе Android, что приводит к нескольким файлам .class . Но после создания файлов .class инструмент «dx» используется для преобразования всех файлов .class в один .dex или Dalvik Executable. Это файл .dex который выполняется на VM Dalvik. Файл .dex оптимизирован для использования памяти, и дизайн в первую очередь определяется совместным использованием данных.
Источник
«65К методов хватит всем» или как бороться с лимитом DEX методов в Android
Это произошло внезапно. Только что вы писали код для своего приложения под андроид, вам это нравилось, и вы наслаждались процессом. Вы добавили крутую библиотеку чтобы получить дополнительные возможности и писать более простой код. Но вместо работающего приложения на выходе вы получаете ужасающую надпись:
Unable to execute dex: method ID not in [0, 0xffff]: 65536
Conversion to Dalvik format failed: Unable to execute dex: method ID not in [0, 0xffff]: 65536
И вы в ступоре, вы неспособны создать DEX файл для APK. Вы не имеете ни малейшего представления о том, что это и как это исправить. И что бы вы не делали, оно будет приводить вас к самому логичному состоянию: ПАНИКА.
Знакомимся с врагом
После того, как вы попробовали все свои обычные трюки (в следующем порядке: чистка проекта, перезапуск IDE, сборка через командную строку, перезагрузка ноутбука, звонок другу и даже десятиминутный перерыв в надежде, что проблема исчезнет сама собой), вы вынуждены признать жестокую правду: проблема все еще здесь. Поэтому было бы неплохо узнать, что стало ее причиной.
В интернете множество постов об этой проблеме: вот один из них, еще один, и еще один; о, а так-же этот и этот тоже. Так что же произошло? По существу, выглядит, что вы столкнулись с чем-то, что часто (и ошибочно) называют Dalvik 65K methods limit. Кратко (спасибо fadden):
Вы можете ссылаться на очень большое число методов в DEX файле, но вызывать можете только первые 65536, потому что это вся память, которая у вас есть для инструкции вызова метода.
[. ] ограничено число методов на которые вы можете сослаться, а не число определенных вами методов. Другими словами, если ваш DEX файл содержит всего несколько методов, но вместе они вызывают 70 000 различных внешне-определенных методов — вы превысите лимит.
Что мы имеем? У вашего приложения слишком много методов, написанных вами или заключенных в библиотечных JAR файлах. По этой причине dx tool не может записать адреса некоторых методов просто потому, что они не помещаются в определенное для этого поле в DEX файле (который в свою очередь содержит скомпилированные Java классы). И именно поэтому проблема должна называться DEX 65K methods limit.
И да, вы все правильно поняли. Эта проблема не исчезнет даже когда андроид перейдет на новый ART рантайм, до тех пор пока Google не решит “поправить” формат DEX или не сменит его на что-то другое.
Давайте посчитаем
Вы наверное удивлены, как вы умудрились зарыть больше 65 000 методов в вашем драгоценном APK. А может и нет. В любом случае, должен быть способ для подсчета этих методов и определения их источника.
Заголовок DEX файла уже содержит информацию о числе ссылок на методы (для ясности, это число представляет уникальные ссылки на методы, а не сумму вызовов для каждого метода). Но мы также хотим видеть, какой пакет добавляет непомерное число этих методов.
Лучший, найденный мной инструмент, был сделан Mihai Parparita, который написал простой bash скрипт, называющийся dex-method-counts. Скрипт очень шустрый и на выходе дает XML, который сопоставляет имя пакета с числом его методов. Другое решение принадлежит Jake Wharton, оно дает точно такой же результат, но требует намного больше времени из-за своей рекурсивной природы (Jake также написал интереснейшую статью по этой теме).
Теперь у нас в руках есть хороший инструмент, так почему бы нам не проверить его на небольшом тестовом приложении? Назовем его SampleApp. Вот код, который содержится в нашей простой Activity:
Я также включил в приложение Google Play Services 5.0.77, хотя я совсем не использую эту библиотеку. Смысл моего поступка прояснится несколькими строками ниже. Теперь давайте проанализируем вывод dex-method-counts (сжатый, для простоты):
Подождите. ЧТО? Я всего лишь определил один метод в моей Activity и уже имею 20 000 методов в моем DEX файле?
Google Play Services: смешанные чувства
Есть ненулевая вероятность что вы знакомы с Google Play Services. Умный ход Google для поддержки API множества своих сервисов, вплоть до Android 2.3 Gingerbread, с новым релизом каждые шесть недель.
Однако все имеет свою цену, которая в данном случае явилась в виде ОГРОМНОГО числа методов которые Play Services несет в себе. Мы говорим приблизительно о 19 000 методов. И при лимите в 65536, это означает, что треть от всех методов, которые мы можем включить, уже исчерпана. Вот так.
Теперь, прежде чем мы перейдем к “решению” этой проблемы, я думаю будут уместны небольшие размышления. Некоторые разработчики как внутри, так и вне Google, разделяют общую точку зрения, которая гласит: “Если вы сталкиваетесь с ограничением, то вы плохой, очень плохой разработчик, вы заслуживаете наказания (а также вы должны гореть в аду)”. С более беспристрастной точки зрения это значит, что вы опрометчиво включили слишком много библиотек, то ли потому что вы слишком ленивы, то ли потому что ваше приложение делает слишком много. Лично я не разделяю эту точку зрения. Я считаю, что это просто оправдания для двух простых вещей:
1. Я не хочу признавать проблему / я не хочу исправлять ее.
2. Я не вышел за лимит, значит я крутой разработчик, а ты делаешь что-то не так.
Может быть, лимит был установлен из следующих соображений: “Этот лимит будет определять грань между хорошим и плохим программистом для всех будущих поколений. Да будет так.” Но что-то я в этом сомневаюсь.
Выбросьте все ненужное
В мире где справедливость торжествует, Google осознал глубину проблемы и решил сократить ущерб, который она наносит, разделив гигантский Play Services на модули, которые могут быть включены в зависимости от функциональности, которую использует ваше приложение. Например, если мое приложение не имеет отношения к играм, совершенно не имеет смысла включать в него все Play Games API. Это наиболее разумный ход, который можно предпринять и который возможно осуществить.
Однако Google не понимает в полной мере проблему, так что лучше мы найдем другой путь решения самостоятельно. Как было сказано, мы будем выбрасывать части google-play-services.jar, те части API, которые нам точно не понадобятся.
Для этого есть пара способов. Вы можете делать это вручную, но помните, что вам придется делать это каждые шесть недель.
Вы можете положиться на библиотеку JarJar, которая позволяет удалять желаемые пакеты из jar файла. Ясно и просто.
Если же вы, как и я, предпочитаете старую добрую командную строку, то вы можете использовать скрипт, который я использую для своих проектов, который называется (вы не поверите) strip_play_services.sh. Управлять работой скрипта можно с помощью конфигурационного файла strip.conf, который идет в комплекте. С помощью него вы можете выбрать модули Play Services Library, которые следует отключить. По существу скрипт делает следующее:
1. Извлекает контент из файла google-play-services.jar
2. Проверяет существует ли strip.conf, и если существует, то использует его для конфигурации, если же нет, то создает новый, записывая туда все модули из Play Services Library
3. Основываясь на strip.conf, удаляет ненужные модули из библиотеки
4. Перепаковывает оставшиеся модули в google-play-services-STRIPPED.jar файл
Вот простая конфигурация файла strip.conf:
actions=true
ads=true
analytics=true
appindexing=true
appstate=true
auth=true
cast=true
common=true
drive=false
dynamic=true
games=false
gcm=true
identity=true
internal=true
location=false
maps=false
panorama=false
plus=true
security=true
tagmanager=true
wallet=false
wearable=true
И все. Теперь для примера давайте посчитаем число методов нашего тестового приложения еще раз и посмотрим, что изменилось:
Это уже что-то. Подбирая подходящую конфигурацию, основываясь на нуждах вашего приложения, вы можете управлять “толщиной” Google Play Services и оставлять больше места для методов, которые вам (возможно) действительно нужны.
Но вы также должны быть очень осторожны. Play Services Library собрана очень хорошо (в плане модульности), и вы можете безопасно удалить модуль “games” не затронув при этом модуль “maps”. Но если вы удалите модуль, который используется другими (внутренний, проще говоря), то ничего не будет работать. Используйте метод проб и ошибок!
Есть ли другой путь?
Конечно есть. Запуск ProGuard для вашего приложения может помочь, так как он удаляет ненужные методы из вашего кода и в дополнение уменьшает размер APK. Но не ожидайте большого сокращения, этого не произойдет.
Другое решение заключается в создании второго DEX файла, который содержит часть вашего кода, доступ к которому вы будете осуществлять через интерфейсы/reflections и который вы будете грузить через кастомный ClassLoader (подробнее). Это решение может быть более эффективным в некоторых случаях. Однако этот путь очень нетривиален.
Я нашел еще одно решение моего хорошего друга Dario Marcato. Он создал Gradle task для удаления ненужных модулей. Если вы используете Gradle, то обязательно попробуйте!.
Источник
Что.DeX файлы в Android?
У меня есть несколько вопросов по поводу DeX файлы
- что это dex файл в Android?
- как dex работает для Android?
- как они используются при отладке приложения для Android?
- они похожи на файлы классов Java?
Мне нужна конкретная информация, пожалуйста, помогите в этом, и любые реальные примеры приветствуются!
4 ответов
об .файл dex:
одна из самых замечательных особенностей Dalvik Virtual Machine (рабочая лошадка в системе Android) заключается в том, что она не использует байт-код Java. Вместо этого был введен доморощенный формат DeX, и даже инструкции байт-кода не совпадают с инструкциями байт-кода Java.
Android программы компилируются в .dex (исполняемый файл Dalvik) файлы, которые, в свою очередь, сжаты в один на устройство. .dex файлы могут быть созданы с помощью автоматического перевода, скомпилированных приложений, написанных на языке программирования Java.
формат файла Dex:
Android имеет документацию на Dalvik Executable Format (.Декс!—15—> файлы). Вы можете узнать больше в официальных документах:Формат Файла Dex
.dex файлы похожи на файлы классов java, но они были запущены под Dalkvik Virtual (DVM) на старые версии Android и скомпилированы во время установки на устройстве в собственный код с искусством на новых версиях Android.
вы можете decompile .Декс с помощью dexdump инструмент, который предоставляется в Android-sdk.
есть также некоторые Методы Обратного Проектирования сделать jar file или java class file С .
скомпилированный файл кода приложения Android.
программы для Android компилируются .DeX (Dalvik Executable) файлы, которые, в свою очередь, молнии в один .apk файл на устройстве. .файлы dex могут быть созданы автоматически Android, путем перевода скомпилированных приложений, написанных на языке программирования Java.
dex файл-это файл, который выполняется на виртуальной машине Dalvik.
Dalvik VM включает в себя несколько функций для оптимизации производительности, проверки и мониторинга, одним из которых является исполняемый файл Dalvik (DEX).
исходный код Java компилируется компилятором Java в .class файлы. Тогда dx (dexer) инструмент, часть Android SDK обрабатывает .class файлы в формате файла с именем DEX который содержит байтовый код Dalvik. The dx инструмент устраняет всю избыточную информацию, которая присутствует в классах. В DEX все классы приложения упакованы в один файл. В следующей таблице приводится сравнение размеров кода для JVM jar-файлов и файлов, обрабатываемых .
таблица сравнивает размеры кода для системных библиотек, приложений веб-браузера и приложения общего назначения (приложение будильника). Во всех случаях DeX tool уменьшил размер кода более чем на 50%.
в стандартных средах Java каждый класс в коде Java приводит к одному . Это означает, что если файл исходного кода Java имеет один открытый класс и два анонимных класса, скажем, для обработки событий, то компилятор java создаст всего три .class файлы.
шаг компиляции одинаковый на платформе Android, что приводит к нескольким .class файлы. Но после .class генерируются файлы, используется инструмент » dx чтобы преобразовать все .class файлы в один .dex , или исполняемый файл Dalvik. Это .dex файл, который выполняется на виртуальной машине Dalvik. The .dex файл был оптимизирован для использования памяти, и дизайн в первую очередь определяется обменом данными.
файл класса здесь содержит стандартный байт-код Oracle JVM.
[ ФАЙЛ КЛАССА JAVA ] > [ ФАЙЛ КЛАССА DEX ]
с тех пор, java .файл класса содержит стандартный байт-код JVM. Но Android-устройства не используют этот формат байт-кода. Вместо этого Android имеет свой собственный формат байтового кода, называемый Dalvik. Байт-коды Dalvik, как и байт-коды Oracle JVM, являются инструкциями машинного кода для теоретического процессора.
в процесс компиляции необходимо преобразовать .файлы классов и любые другие .библиотеки jar в один класс.файл dex, содержащий байт-коды Dalvik. Команда dx сшивает все .класс и. JAR-файлы вместе в один класс.файл dex, написанный в формате байт-кода Dalvik.
Итак, это преобразование .класс и. jar файлы В.файлы dex называются компиляцией Dex, а полученные таким образом файлы называются файлами Dex.
Источник