Build

https://developer.android.com/build
https://developer.android.com/build/annotation-processors
https://developer.android.com/build/jdks
https://developer.android.com/build/configure-app-module
https://developer.android.com/build/manage-manifests
https://developer.android.com/build/custom-build-logic
https://developer.android.com/build/build-variants
https://developer.android.com/build/agp-upgrade-assistant
https://developer.android.com/build/sdk-upgrade-assistant
https://developer.android.com/build/sdk-upgrade-assistant
https://developer.android.com/build/build-analyzer
https://developer.android.com/build/profile-your-build
https://d.android.com/studio/build/shrink-code
https://developer.android.com/build/kotlin-support
https://developer.android.com/build/multidex
https://developer.android.com/tools/adb
https://developer.android.com/build/dependencies
https://developer.android.com/build/native-dependencies
https://developer.android.com/build/remote-repositories
https://developer.android.com/studio/write/lint
https://developer.android.com/google/play/requirements/target-sdk
03.04.2024https://habr.com/ru/companies/cian/articles/804835/
01.10.2020https://habr.com/ru/articles/521522/
NDK

Native Development Kit – набор инструментов, которые помогают работать с кодом, написанным на языках C и C++. NDK предоставляет API для доступа к физическим компонентам девайса, таким как сенсоры. Кроме того NDK позволяет скомпилировать и включить в APK C/C++ код, используя Gradle. NDK часто используется в геймдеве для увеличения производительности и для ручного управления памятью. Для взаимодействия нативного и Java-кода используется собственный интерфейс Java - JNI, он определяет способ взаимодействия байт-кода, который Android компилирует из управляемого кода (написанного на языках программирования Java или Kotlin), с собственным кодом (написанным на C/C++).

JNI

Java Native Interface. Стандартный механизм для запуска кода под управлением JVM, который написан на языках C/C++ или Ассемблере и скомпонован в виде динамических библиотек; позволяет не использовать статическое связывание. Это даёт возможность вызова функции C/C++ из программы на Java, и наоборот.

Android

ОС для смартфонов, планшетов, носимой электроники и бытовых устройств с открытым исходным кодом. Основана на ядре Linux. Android использует собственную реализацию виртуальной машины Java - ART. Позволяет запускать Java-приложения, управляющие устройством через разработанные Google библиотеки.

ART

Android Runtime (ART) - среда выполнения приложений Android, замена Dalvik, преобразовывает байт-код приложений в собственные инструкции, которые выполняются на устройстве.

jar

Java Archive. Содержит классы Java, может использоваться как в Android-приложениях, так и в чистой Java.

aar

Android Archive. Аналогичен модулю приложения Android. Может включать исходный код (классы и методы Java), файлы ресурсов, манифест. Может содержать библиотеки C/C++.

APK (Android Package)

Формат пакета для приложений на платформе Android. Он содержит все необходимые файлы и ресурсы, которые требуются для установки и запуска приложения на устройстве Android. APK-файл представляет собой архив, который можно рассматривать как “упакованный” контейнер для всего, что нужно для работы приложения.

Компоненты APK-файла

META-INF Содержит метаданные о приложении, включая цифровые подписи и сертификаты, которые используются для проверки целостности и подлинности APK.

MANIFEST.MF Файл манифеста, который содержит общую информацию о содержимом архива, например, метаданные подписи.

CERT.RSA Цифровая подпись для проверки целостности файла.

CERT.SF Файл, который содержит список файлов в APK и их хэши для проверки целостности.

res Содержит ресурсы приложения, такие как файлы разметки (XML), изображения и другие ресурсы, которые не являются кодом. Эти файлы упакованы в формат, оптимизированный для быстрого доступа.

assets Содержит произвольные файлы и папки, которые приложение может использовать в процессе выполнения. В отличие от ресурсов в папке res, файлы в папке assets не обрабатываются системой Android и могут быть любого формата.

lib Содержит скомпилированные библиотеки и файлы .so (shared objects) для различных архитектур процессора (например, ARM, x86). Эти библиотеки могут использоваться приложением для выполнения задач на низком уровне или взаимодействия с платформенными функциями.

classes.dex Содержит скомпилированные байт-коды Java (в формате Dalvik Executable) или Kotlin, которые выполняются виртуальной машиной Android (ART/Dalvik). Это основной исполняемый код приложения.

AndroidManifest.xml Основной файл конфигурации, который описывает компоненты приложения (активности, службы, приемники, провайдеры контента) и задает разрешения, необходимые приложению. Этот файл также содержит информацию о версии приложения и других свойствах.

resources.arsc Содержит предварительно скомпилированные ресурсы (например, строки, стили, размеры) в бинарном формате, который позволяет быстро извлекать их во время выполнения приложения.

Структура APK-файла
MyApp.apk
├── AndroidManifest.xml
├── classes.dex
├── res/
│   ├── drawable/
│   ├── layout/
│   ├── mipmap/
│   └── values/
├── assets/
│   └── some_file.txt
├── lib/
│   ├── armeabi/
│   └── x86/
└── META-INF/
    ├── CERT.RSA
    ├── CERT.SF
    └── MANIFEST.MF
Как уменьшить APK

Оптимизация ресурсов. Удалите ненужные ресурсы, используйте форматы изображений с меньшим размером (WebP), не включаете ресурсы для всех разрешений экранов, если они не нужны.

Использование ProGuard и R8. Удалите неиспользуемый код и оптимизируйте его. Обфусцируй и сожми код.

Разделение APK на модули. Создать разные APK для различных архитектур процессоров или разрешений экрана.

Оптимизация библиотек. Удалите лишние зависимости.

Упрощение кода. Не оставляете неиспользуемый код в проекте.

Сжатие файлов. Используйте инструменты для сжатия ресурсов и файлов, такие как pngcrush или jpegoptim для изображений.

Использование shrinkResources. Этот флаг удаляет неиспользуемые ресурсы из APK.

Использование Android App Bundle. Позволяет Google Play автоматически генерировать APK для различных конфигураций устройств. Это помогает сократить размер скачиваемого APK для конечного пользователя.

Как взломать APK

• Распаковать APK. Сразу можно посмотреть AndroidManifest (exported=true). Запустить компоненты. Узнать установлено ли приложение на телефон.

• Просмотреть strings.xml. Там могут лежать ключи.

• Украсть сертификат SSL Pinning из папки raw.

• Перевести .dex в .jar утилитой dex2jar.

• Найти методы Retrofit и получить доступ к коду всех методов работы с сервером.

• Включить debug-меню если разработчики не удаляют его код из release-версии.

.dex

DEX файл – результат компиляции кода Android-приложения. Расшифровывается как Dalvik Executable, но несмотря на это используется и на устройствах со средой исполнения ART. В Java-программах каждый .java файл компилируется в отдельный .class файл. DEX аналогичен файлам .class, но содержит байткод всего приложения (или части приложения в случае Multidex), а не одного класса.

Проблема 64k методов

Это ограничение на количество методов в одном .dex-файле. Максимальное количество методов в .dex-файле равно 65536. На ранних версиях Андроида приложение могло иметь только один .dex-файл. Проблема 64К ограничивала количество методов в приложении. Один класс в Java может иметь максимум 64К методов. В Андроиде .dex-файл сделан по образу .class и поэтому наследует это ограничение. Причина ограничения в том, что под индексы ссылок на методы в java- и dalvik-байткоде выделено 16 бит. Т.е. максимальное число 2^16 = 65536. На ранних версиях Андроида единственным решением было уменьшение количества методов. Для этого использовался Proguard. Сейчас проблема решается включением Multidex. В этом случае приложение может иметь более одного .dex-файла.

AAB (Android App Bundle)

AAB - файловый формат публикации приложений для Android. AAB содержит код и ресурсы, необходимые для конфигурации конкретного устройства. Если пользователь изменит язык устройства или набор функций, магазин приложений может запросить дополнительные разделенные APK для удовлетворения изменившихся требований.

Zygote

Ключевой процесс, который служит для создания новых процессов приложений. Он работает как предзагруженный процесс, из которого создаются копии для каждого приложения с помощью механизма форка (forking). Это позволяет значительно ускорить запуск приложений и сэкономить память.

Инициализация. При загрузке системы Zygote запускается и загружает все необходимые библиотеки, компоненты и классы, общие для всех приложений Android.

Fork (разветвление). Когда нужно запустить новое приложение, Zygote делает “fork” — создаёт новый процесс, который является копией самого процесса Zygote. Это копирование позволяет новому процессу использовать уже загруженные системные ресурсы.

Оптимизация. За счёт предзагрузки общих ресурсов и быстрого разветвления процесс Zygote существенно ускоряет запуск приложений и снижает использование оперативной памяти, так как часть данных (например, классы и библиотеки) остаётся общей для всех приложений.

Приоритеты процессов

  1. Foreground Process (Процесс переднего плана): Наивысший приоритет. Содержит активные пользовательские приложения и процессы, которые напрямую взаимодействуют с пользователем. Всегда остается в памяти и не подвержен убийству системой при нехватке ресурсов.
  1. Visible Process (Процесс видимого приложения): Высокий приоритет. Содержит процессы приложений, которые видимы пользователю, но не активны. Может быть убит системой, если ей нужно освободить память, но только после более низко приоритетных процессов.
  1. Service Process (Процесс службы): Средний приоритет. Содержит процессы, которые выполняют фоновую работу (например, службы, выполняющие долгие задачи). Убиваются только в последнюю очередь, если система нуждается в освобождении ресурсов.
  1. Background Process (Процесс фонового приложения): Низкий приоритет. Содержит приложения, которые не видны пользователю и не выполняют активные задачи. Могут быть убиты системой в первую очередь при нехватке памяти.
  1. Empty Process (Пустой процесс): Наименьший приоритет. Содержит процессы, которые больше не используются и освободили всю память. Убиваются первой, когда системе нужно освободить ресурсы.
Doze Mode

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

Активирование. Doze Mode активируется, когда устройство находится в состоянии покоя. Это происходит, когда экран выключен, и устройство не перемещается в течение определенного времени.

Режимы работы. Когда устройство находится в покое в течение более длительного времени, Doze Mode переходит в более строгий режим экономии энергии, при котором доступ к сети и частичным пробуждениям ограничен еще больше.

Ограничение фоновых операций. Doze Mode ограничивает фоновые операции, такие как синхронизация данных и сетевые запросы, чтобы снизить энергопотребление.

Ограничение активности. Приложения не могут выполнять фоновую работу или получать сообщения до тех пор, пока не произойдут запланированные интервалы пробуждения (standby maintenance windows).

Смарт-уведомления. Приложения могут обрабатывать уведомления в рамках ограничений Doze Mode, но время их доставки может быть отложено до следующего пробуждения устройства.

Пробуждение устройства. Doze Mode не влияет на высоко приоритетные события, такие как входящие вызовы и сообщения, которые могут пробудить устройство. Также может быть пробуждено с помощью действий пользователя, таких как нажатие кнопок или взаимодействие с экраном.

Настройки и исключения. Пользователи могут управлять некоторыми аспектами Doze Mode через настройки устройства, но основное поведение управляется системой. Приложения могут запрашивать исключения от Doze Mode через механизм “whitelist”, если они требуют постоянного фона для критичных задач (например, для приложений для отслеживания местоположения или уведомлений о сообщениях).

Старые устройства. На устройствах, работающих под управлением Android 5.1 или ниже, аналогичные функции экономии энергии называются “App Standby” и имеют более ограниченные возможности по сравнению с Doze Mode.

• Если ваше приложение не выполняет критически важные задачи в фоновом режиме, оно может быть приостановлено в Doze Mode, и система выполнит фоновые операции (такие как синхронизацию данных) только в рамках определенных интервалов. Это помогает сохранить заряд батареи и улучшить общую производительность устройства.

AIDL

Android Interface Definition Language. Язык межпроцессного взаимодействия. Разные процессы не имеют общего пространства памяти, поэтому данные между процессами передаются через сообщения. Интерфейс передачи данных создается на языке AIDL. AIDL поддерживает передачу объектов Parcelable и Serializable.

ANR

Application Not Responding – системный диалог для пользователя, когда приложение зависает. Отображается если: не поступает ответа от UI (нажатие на экран) за 5 сек, broadcastReceiver не завершил выполнение за 10 сек. Частая причина ANR – IO-операции в главном потоке (чтение/запись в бд).

R8

Инструмент оптимизации и уменьшения размера APK в Android, который объединяет функции обфускации (сокрытия исходного кода), оптимизации, уменьшения количества кода (minification) и сжатия ресурсов. Он заменил ProGuard и теперь используется по умолчанию в Android Studio для обработки кода, начиная с Android Studio 3.4. R8 берет на вход .class-файлы, библиотеки, и ресурсы, а затем анализирует их, обфусцирует и оптимизирует, в результате создавая уменьшенную версию APK. Он также поддерживает правила конфигурации (обычно .pro-файлы), с помощью которых можно настраивать, какие классы, методы и поля должны быть исключены из обфускации или минификации.

• Обфускация — R8 переименовывает классы, методы и переменные, делая их имена нечитаемыми. Это затрудняет понимание кода при обратной разработке и увеличивает защиту от реверс-инжиниринга.

• Минификация кода — удаление неиспользуемых классов, методов и полей из кода приложения. R8 анализирует весь код и исключает то, что не влияет на функциональность.

• Оптимизация — R8 анализирует код и улучшает его, удаляя лишние операции, упрощая выражения и т.д. Это снижает нагрузку на процессор и уменьшает потребление памяти.

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

Правила конфигурации для R8
-keep

Cохраняет классы, методы или поля от обфускации и удаления. Часто используется для классов, которые требуются при рефлексии или которые вызываются из сторонних библиотек.

-keep class com.example.myapp.MainActivity
-dontobfuscate

Полностью отключает обфускацию.

-dontobfuscate
-dontoptimize

Отключает оптимизацию (может быть полезно при отладке).

-dontoptimize
@Keep

Исклает класс или метод из обфускации R8. Инструмент сборки сохраняет оригинальные имена классов, методов или полей.

@Keep
data class User(val id: Int, val name: String)
ProGuard

Инструмент для оптимизации, обфускации и уменьшения размера APK в Android.

Вопросы на собесе (20)
  1. Для чего нужен ProGuard?

    ProGuard используется для оптимизации и минификации кода Android-приложений, а также для защиты от реверс-инжиниринга, уменьшая размер APK и затрудняя анализ кода.

  1. Что такое R8?

    Инструмент оптимизации и обфускации кода для Android, заменивший ProGuard. Он уменьшает размер APK, удаляя неиспользуемый код и ресурсы, сокращает имена классов, методов и полей для повышения безопасности, а также улучшает производительность приложения.

  1. Что такое проблема 64k методов?

    Проблема 64k методов возникает, когда количество методов в приложении Android превышает лимит в 65,536, что приводит к ошибке сборки. Это связано с ограничением формата DEX, используемого в Android для компиляции байт-кода.

  1. Разница между implementation и api?

    implementation используется для обозначения зависимостей, которые необходимы только для компиляции и не доступны другим модулям, тогда как api позволяет другим модулям видеть и использовать эти зависимости, включая их публичные API.

  1. Зачем нужна обфускация кода?

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

  1. Как уменьшить APK?

    Применять ProGuard или R8 для минификации и обфускации кода.

    Удалять неиспользуемые ресурсы с помощью инструмента resConfigs.

    Сжимать изображения и использовать форматы WebP.

    Разделять APK на разные версии для разных архитектур с помощью abiFilters.

    Использовать динамическую загрузку функций (Dynamic Delivery).

    Оптимизировать зависимости, избегая избыточных библиотек.

  1. Что такое Doze Mode?

    Doze Mode — это режим экономии батареи в Android, который ограничивает фоновую активность приложений, когда устройство не используется, продлевая время работы от батареи.

  1. Уменьшилась скорость сборки проекта, в чем может быть проблема?

    Увеличения числа зависимостей.

    Использования тяжелых плагинов.

    Неэффективных задач в Gradle.

    Отсутствия кэша сборки.

    Изменений в конфигурациях сборки.

  1. Зачем нужен атрибут targetSdk?

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

  1. Различие между compileSdk и targetSdk?

    compileSdk указывает версию SDK, с которой компилируется проект, а targetSdk определяет, для какой версии SDK приложение оптимизировано. compileSdk позволяет использовать новые API, а targetSdk сообщает системе, как вести себя при взаимодействии с приложением.

  1. Что происходит когда пользователь нажимает на иконку приложения и до вызова Application.onCreate?

    Когда пользователь нажимает на иконку приложения, система создает новый процесс через форк процесса Zygote, загружает ресурсы и компоненты приложения, создает объект Application, а затем вызывает метод Application.onCreate().

  1. Как ускорить холодный старт приложения?

    Отложить инициализацию тяжелых ресурсов в Application.onCreate, делать инициализацию ленивой, использовать библиотеку AppStartup, оптимизовать код с помощью ProGuard и R8.

  1. В чем преимущества многомодульности?

    Улучшает структуру проекта.

    Ускоряет сборку

    Облегчает повторное использование кода и тестирование.

    Упрощает управление зависимостями и параллельную разработку.

  1. Какой путь проделывает сборка от запуска сборки до установки APK?

    Запуск сборки: Инициализация Gradle, считывание конфигураций из build.gradle.

    Компиляция кода: Компиляция Java/Kotlin кода в байт-код, обработка ресурсов.

    Объединение ресурсов: Объединение ресурсов (XML, изображения) в один пакет.

    Создание APK: Компиляция всех артефактов в APK-файл.

    Подпись APK: Подпись APK для обеспечения безопасности.

    Установка: APK копируется на устройство и устанавливается.

  1. Как код приложения превращается в исходники .dex?

    Код приложения компилируется в байт-код с помощью компилятора, а затем преобразуется в формат Dalvik Executable (DEX) с помощью инструмента dx или d8. Этот процесс включает оптимизацию и упаковку кода в .dex файлы, которые затем помещаются в APK для выполнения на Android-устройстве.

  1. Какие есть приоритеты процессов?

    Foreground Process - Наивысший приоритет, активные приложения, не убивается.

    Visible Process - Высокий приоритет, видимые, но неактивные приложения, может быть убит.

    Service Process - Средний приоритет, фоновые службы, убивается последними.

    Background Process - Низкий приоритет, не видимые приложения, убивается первым.

    Empty Process - Наименьший приоритет, неиспользуемые процессы, убивается первым.

  1. Какие существуют инструменты для отладки и профилирования Android-приложений?

    Android Studio Debugger - позволяет устанавливать точки останова, просматривать переменные и управлять выполнением кода.

    Logcat - инструмент для вывода логов, который помогает отслеживать выполнение приложения и диагностировать ошибки.

    Android Profiler - включает инструменты для анализа производительности, памяти, использования CPU и сети.

    StrictMode - позволяет обнаруживать потенциальные проблемы, такие как операции на основном потоке.

    LeakCanary - библиотека для обнаружения утечек памяти.

    Stetho - инструмент для отладки, который предоставляет интерфейс Chrome DevTools для работы с приложением.

    Firebase Performance Monitoring - инструмент для мониторинга производительности приложения в реальном времени.

  1. Как настроить CI/CD?

    Выбрать инструмент: GitHub Actions, GitLab CI, Travis CI, CircleCI, Jenkins и настроить деплой.

  1. Какой инструмент используется для уменьшения размера APK?

    Dalvik

    Jack

    ProGuard

    Lint

  1. Что такое ANR?

    App nothing to request

    Application not responding

    Application nobody request

    Android not responding