gototop gototop

Почта

Логин:

Пароль:


( что это )

Вход в ЭЖ



 

 

Лицензия

 

 

Аккредитация

 

Вход

Войти используя сервисы:

Войти

А так же:
VeriSign , AOL

Поддержка сайта

Телефон поддержки сайта и Электронного журнала

+7 908 952 88 56

пн.-пт. с 9.00 до 17.00

 

также можно связаться по Skype

Skype Me™!

 и   421812859

  • Категории : 40
  • Изображения : 238
  • Комметарии : 1
  • Голосов : 79
  • Просмотры : 38983


Играя в APK Golf

  1. Измерение базовой линии
  2. APK Analyzer
  3. Dex file
  4. Ресурсы
  5. AndroidManifest
  6. 786 Кб (скидка 50%)
  7. AppCompat, мы едва знали тебя
  8. 108 Кбайт (сокращение на 87%)
  9. 6808 байт (сокращение на 94%)
  10. Файл макета (6262 байта, сокращение на 9%)
  11. Название приложения (6034 байта, сокращение на 4%)
  12. Значок запуска (5300 байт, сокращение на 13%)
  13. Манифест (5252 байта, сокращение 1%)
  14. Хак Proguard (4984 байта, 5% сокращение)
  15. Расхождение в размере файла (2608 байт, сокращение на 21%)
  16. Компрессионные хаки (2599 байт, снижение на 0,5%)
  17. Hello ADB (2462 байта, 5% сокращение)
  18. Сокращение ссылок на метод (2179 байт, сокращение на 12%)
  19. Оптимизация Dex (1961 байт, сокращение на 10%)
  20. Понимание манифеста (1961 байт, сокращение на 0%)
  21. Непонимание манифеста (1777 байт, сокращение на 9%)
  22. UTF-8 Манифест
  23. Шестнадцатеричный Манифест
  24. Готово? (1757 байт, сокращение 1%)
  25. Этап 5: Принятие
  26. Благодарю вас

В гольфе выигрывает наименьшее количество очков.

Давайте применим этот принцип к Android. Мы собираемся поиграть в APK golf и создать наименьшее возможное приложение, которое можно установить на устройстве под управлением Oreo.

Измерение базовой линии

Мы начнем с приложения по умолчанию, созданного Android Studio. Давайте создать хранилище ключей , подпишите приложение и измерьте размер файла в байтах, используя stat -f% z $ filename.

Мы также установим APK на Nexus 5x под управлением Oreo, чтобы убедиться, что все работает.

Мы также установим APK на Nexus 5x под управлением Oreo, чтобы убедиться, что все работает

Красивая. Наш APK весит примерно 1,5 Мб.

APK Analyzer

1.5Mb кажется много, учитывая то, что делает наше приложение, поэтому давайте изучим проект и поищем любые быстрые победы. Android Studio сгенерировал:

  • MainActivity, которая расширяет AppCompatActivity.
  • Файл макета с корневым представлением ConstraintLayout.
  • Файлы значений, содержащие три цвета, один строковый ресурс и тему.
  • AppCompat и ConstraintLayout поддерживают библиотеки.
  • Один AndroidManifest.xml
  • Квадратные, круглые и передние значки запуска ПНГ.

Иконки кажутся самой легкой целью, учитывая, что всего имеется 15 изображений и 2 файла XML в mipmap-anydpi-v26. Давайте посчитаем, что с помощью Android Studio APK Analyzer ,

Вопреки нашим первоначальным предположениям, кажется, что наш файл Dex является самым большим, и что ресурсы занимают только 20% от размера APK.

Размер файла classes.dex 74% res 20% resources.arsc 4% META-INF 2% AndroidManifest.xml <1%

Давайте рассмотрим, что делает каждый файл в отдельности.

Dex file

Class.dex является крупнейшим виновником в 73%, и, следовательно, наша первая цель. Этот файл содержит весь наш скомпилированный код в Формат Dex , а также ссылки на внешние методы в платформе Android и библиотеке поддержки.

Пакет android.support содержит более 13 000 методов, что кажется чрезмерным для приложения Hello World.

Ресурсы

В нашем каталоге res содержится огромное количество файлов макетов, рисованных объектов и анимации, которые не были сразу видны в пользовательском интерфейсе Android Studio. Опять же, они были извлечены из библиотеки поддержки и весят примерно 20% от размера APK.

Файл resources.arsc также содержит ссылку на каждый из этих ресурсов.

Папка META-INF содержит файлы CERT.SF, MANIFEST.MF и CERT.RSA, которые необходимы для v1 APK подпись , Если злоумышленник изменит код в нашем APK, подпись не будет совпадать, что означает, что пользователь будет спасен от выполнения сторонних вредоносных программ.

MANIFEST.MF перечисляет файлы в APK, тогда как CERT.SF содержит дайджест манифеста, а также отдельный дайджест каждого файла. CERT.RSA содержит открытый ключ, который используется для проверки целостности CERT.SF.

Здесь нет очевидных целей.

AndroidManifest

AndroidManifest выглядит очень похоже на наш исходный файл ввода. Единственным исключением является то, что такие ресурсы, как строки и элементы рисования, были заменены целочисленными идентификаторами ресурсов, начиная с 0x7F.

Мы не пытались включить минификацию и сокращение ресурсов в файле build.gradle нашего приложения. Давайте попробуем.

android {buildTypes {release {minifyEnabled true shrinkResources true proguardFiles getDefaultProguardFile ('proguard-android.txt'), 'proguard-rules.pro'}}} -keep класс com.fractalwrench. ** {*; }

Установка minifyEnabled в true включает Proguard , который удаляет неиспользуемый код из нашего приложения. Он также запутывает имена символов, затрудняя обратное проектирование приложения.

shrinkResources удалит из нашего APK любые ресурсы, на которые нет прямой ссылки. Это может вызвать проблемы, если вы используете отражение для косвенного доступа к ресурсам, но это не относится к нашему приложению.

786 Кб (скидка 50%)

Мы уменьшили размер APK наполовину, не оказав заметного влияния на наше приложение.

Если вы еще не включили minifyEnabled и shrinkResources в своем приложении, это самая важная вещь, которую вы должны убрать из этого поста. Вы можете легко сэкономить несколько мегабайт пространства , всего за пару часов настройки и тестирования.

AppCompat, мы едва знали тебя

classes.dex теперь занимает 57% APK. Большинство ссылок на методы в нашем файле Dex принадлежат пакету android.support, поэтому мы собираемся удалить библиотеку поддержки. Для этого мы будем:

  • Полностью удалите блок зависимостей из нашего build.gradle

зависимость {реализация 'com.android.support:appcompat-v7:26.1.0' реализация 'com.android.support.constraint: компоновка ограничений: 1.0.2'}

  • Обновите MainActivity для расширения android.app.Activity

Открытый класс MainActivity расширяет активность

  • Обновите наш макет, чтобы использовать один TextView.

&lt;? xml version = "1.0" encoding = "utf-8"?> <TextView xmlns: android = "http://schemas.android.com/apk/res/android" android: layout_width = "match_parent" android: layout_height = "match_parent" android: gravity = "center" android: text = "Hello World!" />

  • Удалите styles.xml и удалите атрибут android: theme из элемента <application> в AndroidManifest
  • Удалить colors.xml
  • Выполните 50 отжиманий во время синхронизации

108 Кбайт (сокращение на 87%)

Святая корова, мы только что достигли примерно 10-кратного сокращения с 786 КБ до 108 КБ. Единственное заметное изменение - это цвет панели инструментов, который теперь использует тему ОС по умолчанию.

Каталог res теперь занимает 95% от нашего размера APK из-за всех этих значков запуска. Если бы эти PNG были предоставлены нашим дизайнером, то мы могли бы попробовать преобразование их в WebP , который является более эффективным форматом файла, поддерживаемым API 15 и выше.

К счастью, Google уже оптимизировал наши графики, но если бы это было не так, ImageOptim может также оптимизировать и удалить ненужные метаданные из PNG.

Давайте будем плохим гражданином и заменим все наши значки запуска одной черной точкой размером 1 пиксель, помещенной в неквалифицированную папку res / drawable. Это изображение весит 67 байт.

6808 байт (сокращение на 94%)

Мы избавились почти от всех наших ресурсов, поэтому не удивительно, что мы увидели сокращение нашего размера APK примерно на 95%. На ресурсы по-прежнему ссылаются resources.arsc:

  • 1 файл макета
  • 1 строковый ресурс
  • 1 значок запуска

Давайте начнем с вершины.

Файл макета (6262 байта, сокращение на 9%)

Фреймворк Android будет раздувать наш XML-файл и автоматически создайте объект TextView для установки в качестве contentView для Activity.

Мы могли бы попытаться пропустить посредника, удалив файл XML и установив contentView программно. Размер наших ресурсов уменьшится, так как XML-файл будет на один меньше, но наш Dex-файл увеличится, так как мы будем ссылаться на дополнительные методы TextView.

TextView textView = новый TextView (это); textView.setText ("Hello World!"); setContentView (TextView);

Похоже, наш компромисс сработал, и мы уменьшили до 5710 байтов.

Название приложения (6034 байта, сокращение на 4%)

Давайте удалим strings.xml и заменим метку android: в AndroidManifest на «A». Это может показаться небольшим изменением, но удаляет запись из resources.arsc, уменьшает количество символов в манифесте и удаляет файл из каталога res. Каждое немного помогает - мы только что сохранили 228 байтов.

Значок запуска (5300 байт, сокращение на 13%)

документация для resources.arsc в хранилище платформы Android сообщает, что на каждый ресурс в APK ссылается resources.arsc с целочисленным идентификатором. Эти идентификаторы имеют два пространства имен:

0x01: системные ресурсы (предустановленные в framework-res.apk)

0x7f: ресурсы приложения (включены в приложение .apk)

Так что же происходит с нашим APK, если мы ссылаемся на ресурс в пространстве имен 0x01? Мы должны быть в состоянии получить более приятный значок и одновременно уменьшить размер нашего файла.

Android: значок = "@ андроид: рисуем / btn_star"

Само собой разумеется, но вы никогда не должны доверять таким системным ресурсам в производственном приложении. Этот шаг не пройдет проверку Google Play, и, учитывая, что некоторые производители, как известно, переопределяют цвет белый , действовать с осторожностью.

Манифест (5252 байта, сокращение 1%)

Мы еще не коснулись манифеста.

android: allowBackup = "true" android: supportRtl = "true"

Удаление этих атрибутов экономит нам 48 байтов.

Хак Proguard (4984 байта, 5% сокращение)

Похоже, что BuildConfig и R все еще включены в файл Dex.

-поддержите класс com.fractalwrench.MainActivity {*; }

Уточнение нашего правила Proguard исключит эти классы.

Давайте дадим нашей активности запутанное имя. Proguard делает это автоматически для обычных классов, но так как имя класса Activity может быть вызвано через Intents, по умолчанию это не скрывается.

MainActivity -> c.java

com.fractalwrench.apkgolf -> копия

В настоящее время мы подписываем наше приложение с подписью v1 и v2. Это кажется расточительным, особенно когда v2 предлагает превосходная защита и производительность Хешируя весь АПК.

Наша сигнатура v2 не видна в анализаторе APK, так как она включена в виде двоичного блока в самом файле APK. Наша подпись v1 видна в виде файлов CERT.RSA и CERT.SF.

Давайте снимем флажок подписи v1 в пользовательском интерфейсе Android Studio и создадим подписанный APK. Мы также попробуем то же самое в обратном порядке.

Размер подписи v1 3511 v2 3307

Похоже, что теперь мы будем использовать v2.

Пришло время редактировать наш APK вручную. Мы будем использовать следующие команды:

# 1. Создайте неподписанный apk ./gradlew assemblyRelease # 2. Распакуйте архив unzip app-release-unsigned.apk -d app # Внесите изменения # 3. Zip-архив zip -r app app.zip # 4. Запустите zipalign zipalign - v -p 4 app-release-unsigned.apk app-release-align.apk # 5. Запустите apksigner со знаком v2 подписи apksigner - v1-signature-enabled false --ks $ HOME / fake.jks --out sign- release.apk app-release-unsigned.apk # 6. Проверить подпись apksigner проверить подписанный-release.apk

Подробный обзор подписи APK можно найти Вот , Таким образом, gradle генерирует неподписанный архив, zipalign изменяет выравнивание байтов несжатых ресурсов, чтобы улучшить использование ОЗУ при загрузке APK, и, наконец, APK криптографически подписывается.

Наш неподписанный и невыровненный APK весит 1902 байта, что указывает на то, что этот процесс добавляет около 1 КБ.

Расхождение в размере файла (2608 байт, сокращение на 21%)

Weird! Разархивирование неподписанного APK и его подписание вручную удаляет META-INF / MANIFEST.MF, экономя нам 543 байта. Если кто-нибудь знает, почему это так, пожалуйста, свяжитесь с нами!

Теперь в нашем подписанном APK осталось 3 файла. Однако мы также можем избавиться от resources.arsc, потому что мы не определяем никакие ресурсы!

Это оставляет нас с манифестом и файлом classes.dex, каждый из которых примерно одинакового размера.

Компрессионные хаки (2599 байт, снижение на 0,5%)

Давайте изменим все наши оставшиеся строки на «c», обновим наши версии до 26, а затем сгенерируем подписанный APK.

compileSdkVersion 26 buildToolsVersion "26.0.1" defaultConfig {applicationId "cc" minSdkVersion 26 targetSdkVersion 26 versionCode 26 versionName "26"} <manifest xmlns: android = "http://schemas.android.com/apk/res/android" package = "cc"> <application android: icon = "@ android: drawable / btn_star" android: label = "c"> <активность android: name = "ccc">

Это спасло нас 9 байтов.

Хотя количество символов в файле не изменилось, мы изменили частоту символа 'c'. Это позволяет алгоритму сжатия еще больше уменьшить размер файла.

Hello ADB (2462 байта, 5% сокращение)

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

Оболочка adb am start -a android.intent.action.MAIN -n cc / .c

Вот наш новый манифест:

<manifest xmlns: android = "http://schemas.android.com/apk/res/android" package = "cc"> <application> <Activity android: name = "c" android: exported = "true" /> </ application> </ manifest>

Мы также избавились от нашего значка запуска.

Сокращение ссылок на метод (2179 байт, сокращение на 12%)

Наши первоначальные требования заключались в создании APK, который устанавливается на устройстве. Пора Hello World, чтобы пойти.

Наше приложение ссылается на методы в TextView, Bundle и Activity. Мы можем уменьшить размер файла Dex, удалив это действие и заменив его собственным классом Application. Наш dex-файл теперь должен ссылаться только на один метод - конструктор Application.

Наши исходные файлы теперь выглядят так:

пакет сс; импорт android.app.Application; открытый класс c расширяет приложение {} <manifest xmlns: android = "http://schemas.android.com/apk/res/android" package = "cc"> <приложение android: name = ". c" /> </ манифеста>

Мы будем использовать adb, чтобы убедиться, что APK успешно установлен, а также можем проверить это через приложение «Настройки».

Оптимизация Dex (1961 байт, сокращение на 10%)

Я провел несколько часов, исследуя Формат файла Dex для этой оптимизации, поскольку различные механизмы, такие как контрольные суммы и смещения, затрудняют ручное редактирование.

Однако, короче говоря, оказывается, что единственным требованием для установки APK является наличие файла classes.dex. Поэтому мы просто удалим исходный файл, запустим в терминале touch classes.dex и получим сокращение на 10% за счет использования пустого файла.

Иногда самое глупое решение - лучшее.

Понимание манифеста (1961 байт, сокращение на 0%)

Наш манифест из неподписанного APK находится в двоичном формате XML, который, как представляется, официально не документирован. Мы можем использовать HexFiend редактор для управления содержимым файла.

Мы можем догадаться о паре интересных элементов в заголовке файла - первые четыре байта кодируют 38, то есть тот же номер версии, что и файл Dex. Следующие два байта кодируют 660, что удобно для размера файла.

Давайте попробуем удалить байт, установив targetSdkVersion в 1 и обновив заголовок размера файла до 659. К сожалению, система Android отклоняет это как недопустимый APK, так что, похоже, здесь есть некоторая дополнительная сложность.

Непонимание манифеста (1777 байт, сокращение на 9%)

Давайте введем фиктивные символы по всему файлу, затем попытаемся установить APK, не меняя размер файла. Это определит, есть ли контрольная сумма на месте или наши изменения аннулировали значения смещения в заголовке файла.

Удивительно, но следующий манифест интерпретируется как действительный APK на Nexus 5X под управлением Oreo:

Удивительно, но следующий манифест интерпретируется как действительный APK на Nexus 5X под управлением Oreo:

Я думаю, что я слышу, как Android Framework Engineer отвечает за поддержание BinaryXMLParser.java, очень громко кричащего в подушку.

Чтобы максимизировать нашу прибыль, мы собираемся заменить эти фиктивные символы нулевыми байтами. Это облегчит просмотр важных частей файла в HexFiend, а также получит байты от нашего более раннего хакерского сжатия.

UTF-8 Манифест

Это основные компоненты манифеста, без которых APK не может быть установлен.

Несколько вещей сразу очевидны - например, манифест и теги пакета. VersionCode и имя пакета также находятся в пуле строк.

Шестнадцатеричный Манифест

Шестнадцатеричный Манифест

При просмотре файла в шестнадцатеричном формате в заголовке файла отображаются значения, которые описывают пул строк и другие значения, например размер файла 0x9402. Строки также имеют интересную кодировку - если они превышают 8 байтов, их общая длина указывается в 2 предыдущих байтах.

Тем не менее, это не похоже, что есть гораздо больше возможностей для получения прибыли здесь.

Готово? (1757 байт, сокращение 1%)

Давайте проверим окончательный APK.

После всего этого времени я оставил свое имя в APK через подпись v2. Давайте создадим новое хранилище ключей, которое использует хак для сжатия.

Это сэкономило нам 20 байтов.

Этап 5: Принятие

1757 байт чертовски мало, и, насколько я знаю, это самый маленький APK из всех существующих.

Тем не менее, я достаточно уверен, что кто-то из сообщества Android может сделать дальнейшую оптимизацию, которая превзойдет мой счет. Если вам удастся улучшить 1757 байт, пожалуйста, отправить PR в хранилище где находится самый маленький APK, или связаться через Twitter ,

Благодарю вас

Надеюсь, вам понравилось узнавать о внутренностях Android APK. Если у вас есть какие-либо вопросы, отзывы или вы хотите предложить тему для меня, пожалуйста, напишите связаться через Twitter !

Lt;?
Encoding = "utf-8"?
Готово?

Новости

Погода

Наши учредители

 

администрации г. Кемерово

    Начальник управления

  Чернова Нина Александровна

  Адрес: 650000, г. Кемерово

  пр. Советский, 54

  тел. приемной: (384-2) 36-46-19

 

Председатель комитета

Казаченко Ольга Алексеевна

  Адрес: 650000, г. Кемероово,

  Притомская Набережная, 7

  тел. приемной: (384-2) 36-81-71

Российское образование

 

 

Школьная форма


Форма

Голосования

Ваше отношение к инклюзивному образованию (обучению детей-инвалидов в общеобразовательной школе).
 
Управление образования администрации г.Кемерово
Какая главная проблема современных школьников?