Android Interview Review
3.54K members
233 links
Популярные вопросы и ответы с собеседований на Android-разработчика.

Канал для Java-разработчиков @JavaSobes

Связаться с нами @SobesAdmin

https://itsobes.ru
Download Telegram
to view and join the conversation
Выпуск подкаста о том, почему компании часто не дают фидбэк после неудачного собеседования.

https://softskills.audio/2018/04/30/episode-107-no-interview-feedback-and-newsletter-politics/

#пятница
В чем разница между invalidate() и requestLayout()?

Метод View.invalidate() шедулит перерисовку view. Результат вызова этого метода – асинхронный вызов onDraw().
invalidate() используется, когда нужно перерисовать view без изменения размеров, например когда изменяется цвет бэкграунда.

Метод View.requestLayout() асинхронно вызывает методы onMesure() и onLayout() на текущей view и на всех родителях.
Этот метод используется, чтобы обновить view после изменения размеров.

На картинке изображен жизненный цикл view и то, как на него влияют invalidate() и requestLayout(), но есть одна неточность: requestLayout() не гарантирует вызов onDraw().

Чтобы обновить view, requestLayout() следует вызывать вместе с invalidate().

#View
Для чего нужен метод View.forceLayout()?

При вызове метода requestLayout() на ViewGroup, новое измерение дочерних view не гарантируется. Вместо этого используются закэшированные значения.

Метод View.forceLayout() инвалидирует закэшированные размеры view, чем провоцирует измерение, при вызове requestLayout() на родительском ViewGroup.

forceLayout() не вызывает requestLayout() на view, или ее родителях. Этот метод используется только в связке с requestLayout().

#View
Работает ли assert в Андроиде?

В Java канале мы писали о том, как работает assert в JVM. Но в Андроиде используется виртуальная машина Dalvik или ART, в зависимости от версии ОС, а не стандартная JVM.

По-умолчанию assert в андроид-приложении не работает.

В Dalvik ассерты включаются командой adb shell setprop debug.assert 1, но эта настройка ненадежна и не работает на некоторых версиях Андроид. В ART ассерты и вовсе убрали.

Если использовать assert, то линтер в Android Studio покажет warning и предложит заменить на конструкцию:


if (BuildConfig.DEBUG && !(&jt;assert_condition>)) { throw new AssertionError() }


#System
Чем Dalvik отличается от ART?

Dalvik – это виртуальная машина, которая использовалась с первой версии до Android v5.0.

ART (Android Runtime) – это среда выполнения, которая заменила Dalvik начиная с Android v5.0.

Основное отличие ART от Dalvik – это стратегия компиляции байткода в машинный код.

Dalvik использует JIT-компиляцию (Just-in-time), при которой байткод компилируется во время работы программы.

ART до Android v7.0 использует AOT-компиляцию (Ahead-of-Time), при которой приложение компилируется в машинный код во время установки. В Android v7.0 в ART был добавлен JIT-компилятор в дополнение к AOT. Смешанный подход помог смягчить недостатки AOT-компиляции.

#System
В чем достоинства и недостатки ART?

Достоинства ART в сравнении с Dalvik:
• Приложения быстрее запускаются и в целом увеличена производительность приложений;
• Улучшена работа сборщика мусора;
• Уменьшено потребление заряда батареи.

Недостатки ART:
• Приложения занимают больше места на диске устройства;
• Загрузка систему при включении занимает больше времени.

#System
Что такое .dex файл?

DEX файл – это результат компиляции кода Android-приложения. DEX расшифровывается как Dalvik Executable, но несмотря на это используется и на устройствах со средой исполнения ART.

В Java-программах каждый .java файл компилируется в отдельный .class файл. DEX аналогичен файлам .class, но содержит байткод всего приложения (или части приложения в случае Multidex), а не одного класса.

#System
Что такое проблема 64К методов?

Проблема 64К методов – это ограничение на количество методов в одном .dex-файле. Максимальное количество методов в .dex-файле равно 65536.

На ранних версиях Андроида приложение могло иметь только один .dex-файл. Проблема 64К ограничивала количество методов в приложении.

Почему ограничение в 65536 методов, а проблема называется 64K?

«‎K»‎ значит Kilo, что в computer science значит 1024*x. 1024*64 = 65536.

Почему возникла эта проблема?

Один класс в Java может иметь максимум 64К методов.
В Андроиде .dex-файл сделан по образу .class и поэтому наследует это ограничение.

Причина ограничения в том, что под индексы ссылок на методы в java- и dalvik-байткоде выделено 16 бит. Т.е. максимальное число 2^16 = 65536.

Как решать проблему?

На ранних версиях Андроида единственным решением было уменьшение количества методов. Для этого использовался Proguard.

Сейчас проблема решается включением Multidex. В этом случае приложение может иметь более одного .dex-файла.

#Syntax
Опишите структуру APK-файла

APK (Android Package) – это формат файла, который используется для распространения и установки мобильных приложений в операционной системе Android.

APK представляет собой архив, который содержит следующие файлы:

• Папка META-INF:
MANIFEST.MF – манифест-файл, который содержит SHA-хэши всех файлов в APK-пакете;
• Сертификат приложения;
• Файлы с дополнительной метаинформацией.

lib – папка, содержащая скомпилированный код платформенно-зависимых библиотек. lib содержит подкаталоги для соответствующих платформ: armeabi, armeabi-v7a, arm64-v8a, x86, x86_64, mips.

res – папка, в которой лежат андроид-ресурсы в Binary XML формате.

assets – папка, содержащая ассеты приложения.

AndroidManifest.xml – манифест Андроид-приложения. Этот файл хранится в скомпилированном Binary XML формате.

classes.dex – один или несколько файлов, которые представляют собой код приложения, скомпилированный в Dalvik-байткод.

resources.arsc – файл, в котором хранится таблица маппинга id ресурсов в соответствующие файлы.

#Build
Как собирается Android-приложение?

Сборка Android-приложения состоит из следующих шагов:

1. Компилирование Java/Kotin-исходников.

Компилятор создает .class-файлы, содержащие java-байткод.

.java source -> javac compiler -> .class files
.kt source -> kotlinc compiler -> .class files


2. Конвертация Java-байткода в Dalvik-байткод.

Для конвертации используется утилита dx. На вход подаются .class-файлы, скомпилированные на предыдущем шаге, и .jar/.aar-файлы скомпилированных библиотек. dx создает файлы формата .dex, которые содержат Dalvik-байткод.

.class, .jar, .aar -> dx -> classes.dex


3. Сборка ресурсов и .dex-файлов в APK.

Этот шаг выполняется утилитой aapt (Android Asset Packaging Tool).

classes.dex, resource files -> aapt -> .apk file


4. Оптимизация и подпись .apk-файла.

Для оптимизации APK используется утилита zipalign. APK является zip-архивом. zipalign выравнивает файлы в архиве определенным образом, что уменьшает использование RAM, при работе приложения.

Подпись приложения выполняется утилитой apksigner.

.apk file -> zipalign -> apksigner -> signed .apk file


До Build Tools v24.0.3 подпись APK выполнялась утилитой jarsigner, которая была создана для подписи .jar-файлов, и zipalign применялся к уже подписанному APK.

.apk file -> jarsigner -> zipalign -> signed .apk file


#Build
В чем разница между jar и aar?

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

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

AAR – Android Archive. Так же как и JAR является zip-архивом, но может использоваться только в Android-приложении. AAR содержит скомпилированный исходный код в файле classes.jar, Android-ресурсы, AndroidManifest, и другие файлы, входящие в состав APK.

#Build
Что такое Proguard?

Proguard – это инструмент обфускации и оптимизации Java-кода. Proguard может использоваться как на чистом Java-, так и на Android-приложении, но в мире Андроида Proguard популярнее по двум причинам.

Во-первых, Proguard удаляет неиспользуемые классы и методы из уже скомпилированного приложения. Это позволяло решать проблему 64К методов до появления MultiDex.

Во-вторых, Java- и Dalvik-байткод легко декомпилировать. Для серверного Java-приложения это не проблема, а вот к байткоду приложения под Android доступ имеет любой пользователь.
Proguard обфусцирует код, что усложняет задачу декомпиляции.

#Build
Как Proguard удаляет неиспользуемый код?

Одна из функций Proguard – это удаление неиспользуемого кода программы.

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

Proguard запускается после компиляции исходного кода и получения .class файлов, но до конвертации в dex.

Proguard строит граф использования классов, методов и полей, начиная от входных точек программы, как показано на картинке.

Входные точки программы задаются в файлах конфигурации правилом -keep. Android Gradle Plugin генерирует дефолтный файл c правилами для сохранения базовых компонент и специфичных для андроида классов, таких как View.

Если класс, метод или поле используется только через Reflection, Proguard пометит этот компонент как неиспользуемый и удалит. Это является частой причиной крэшей ClassNotFoundException при использовании Proguard.
Для сохранения таких компонентов нужно добавить правила -keep в файл конфигурации.

После сборки приложения с Proguard, генерируется файл usage.txt, в котором хранится список всех удаленных компонентов.

#Build
Как Proguard обфусцирует код?

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

Proguard запускает обфускацию после удаления неиспользуемого кода. Переименовываются все компоненты программы, кроме тех, что были явно исключены в файле Proguard-правил.

После обфускации кода Proguard генерирует файл mapping.txt, который содержит маппинг новых имен к старым. Этот файл используется для декодирования обфусцированных стектрейсов. Обычно его загружают на сервис крэш-репортов (например Crashlytics), который автоматически декодирует логи.
Для ручного декодирования используется инструмент Retrace.

Proguard использует новые обфусцированные имена при каждом следующем билде. Поэтому, во-первых, надо сохранять файл mapping.txt для каждой версии программы. Во-вторых, нельзя использовать динамические имена классов как ключи для сохранения данных в персистентном хранилище.

Также обфускация делает невозможным обращение к членам класса через Reflection.
Для сохранения имен используется правило -keep.

#Build
Что такое Consumer Proguard?

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

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

Если библиотека распространяется в формате jar, то разработчики часто документируют Proguard-правила. Пользователям библиотеки достаточно скопировать их в конфигурационный файл своего проекта.

Если же библиотека поставляется в формате aar, то разработчики библиотеки могут запаковать Proguard-правила в aar-пакет.

Для этого в gradle-файле библиотеки используется проперти consumerProguardFiles, которая принимает файл с правилами Proguard.

В этом случае пользователям библиотеки не надо ничего делать. При сборке приложения Gradle автоматически проверяет все aar-библиотеки на наличие consumer proguard файлов и мержит их с конфигурационным файлом проекта.

#Build
Дорогие друзья, поздравляем вас с наступающим Новым Годом! Желаем каждому из вас найти в следующем году работу мечты и надеемся, что наш канал вам в этом поможет.

Редакция нашего канала уходит на новогодние каникулы. А для вас мы подготовили топ 5 постов и навигацию по темам канала.

Помните, лучший способ поздравить канал – поделиться ссылкой с друзьями. Или дать фидбэк в бота обратной связи @AndroidSobesBot.

С наступающим!
Что такое Android Jetpack?

Android Jetpack – это набор библиотек и инструментов, созданный командой Google для упрощения разработки под Android.

Проект Jetpack анонсирован в 2018 году. Jetpack-библиотеки используют пакет androidx.*. Support-библиотеки также стали частью Jetpack.

Библиотеки, входящие в Jetpack логически разделены на четыре вида:

1. Foundation – базовые библиотеки, которые помогают уменьшить бойлерплейт код. Сюда входят AppCompat, Android KTX, Test.

2. Architecture Components – это библиотеки, используемые для построения архитектуры приложения. Среди них LiveData, ViewModel, Room, WorkManager.

3. Behavior – библиотеки-врапперы для функциональности, предоставляемой Android SDK. Созданы для улучшения стандартного Android API: Permissions, Notifications, CameraX.

4. UI – компоненты, помогающие работать с фрагментами, лэйаутами и анимацией. Среди прочих сюда входит Jetpack Compose.

#Jetpack