Как отладить приложение на девайсе?
Для удаленной отладки используется технология Android Debug Bridge. Она включает три компонента:
• adbd – демон на стороне девайса, который принимает и выполняет команды.
• ADB Сервер – демон на стороне компьютера, с которого ведется отладка. Принимает запросы от отладочных клиентов на TCP порт 5037. Служит единой точкой доступа к удаленной отладке. Запускается при первом старте adb клиента.
• Клиенты – различные приложения, которые пользуются инструментами отладки. Самое простое – консольный клиент
Сервер передает команды от клиентов в adbd на эмуляторах через TCP порты, либо в adbd на реальных девайсах через USB или WiFi.
Помимо самого дебаггера для отладки применяются дополнительные инструменты, такие как Android profiler и Device File Explorer. Для исследования проблем полезны баг репорты.
Если необходимо отладить web-приложение, используется специальная фича Chrome DevTools.
#Tools
Для удаленной отладки используется технология Android Debug Bridge. Она включает три компонента:
• adbd – демон на стороне девайса, который принимает и выполняет команды.
• ADB Сервер – демон на стороне компьютера, с которого ведется отладка. Принимает запросы от отладочных клиентов на TCP порт 5037. Служит единой точкой доступа к удаленной отладке. Запускается при первом старте adb клиента.
• Клиенты – различные приложения, которые пользуются инструментами отладки. Самое простое – консольный клиент
adb
из SDK. Более сложные клиенты могут использовать adb
внутри, либо самостоятельно подключаться к порту ADB сервера.Сервер передает команды от клиентов в adbd на эмуляторах через TCP порты, либо в adbd на реальных девайсах через USB или WiFi.
Помимо самого дебаггера для отладки применяются дополнительные инструменты, такие как Android profiler и Device File Explorer. Для исследования проблем полезны баг репорты.
Если необходимо отладить web-приложение, используется специальная фича Chrome DevTools.
#Tools
Какие классы служат для доступа к сенсорам?
Таких классов четыре:
• SensorManager – точка входа для работы с сенсорами и listener-ами их событий. Системный сервис, получаемый по имени
• Sensor – представляет отдельно взятый сенсор. Дает различную метаинформацию (энергопотребление, точность, производителя, и т.д.);
• SensorEventListener – интерфейс для реализации обработчиков событий, приходящих из сенсоров. В нём реализуется логика обработки входящих данных;
• SensorEvent – отдельное событие из сенсора: данные и точность их измерения.
Для подробного изучения возможностей сенсоров на официальном сайте есть полный гайд.
#Hardware
Таких классов четыре:
• SensorManager – точка входа для работы с сенсорами и listener-ами их событий. Системный сервис, получаемый по имени
Context.SENSOR_SERVICE
;• Sensor – представляет отдельно взятый сенсор. Дает различную метаинформацию (энергопотребление, точность, производителя, и т.д.);
• SensorEventListener – интерфейс для реализации обработчиков событий, приходящих из сенсоров. В нём реализуется логика обработки входящих данных;
• SensorEvent – отдельное событие из сенсора: данные и точность их измерения.
Для подробного изучения возможностей сенсоров на официальном сайте есть полный гайд.
#Hardware
Как передать параметры в конструктор фрагмента?
Параметры передаются в конструктор Fragment-а через Bundle, с помощью метода
Распространенная ошибка передавать данные через кастомный конструктор. Использовать не-дефолтные конструкторы фрагментов не рекомендуется, потому что фрагмент может быть уничтожен и пересоздан вследствие изменений конфигурации (например при повороте экрана).
Использование пары методов
#Fragment
Параметры передаются в конструктор Fragment-а через Bundle, с помощью метода
Fragment.setArgument(Bundle)
. Переданный бандл может быть получен через Fragment.getArguments()
в соответствующем методе жизненного цикла фрагмента.Распространенная ошибка передавать данные через кастомный конструктор. Использовать не-дефолтные конструкторы фрагментов не рекомендуется, потому что фрагмент может быть уничтожен и пересоздан вследствие изменений конфигурации (например при повороте экрана).
Использование пары методов
setArguments
/getArguments
гарантирует, что при пересоздании Bundle будет сериализован/десериализован, и данные восстановятся.#Fragment
Перечислите доступные хранилища данных
• Shared Preferences – приватные примитивные данные в виде ключ-значение.
• SQLite – структурированные данные в приватной базе данных.
• Внешнее хранилище – общедоступное файловое хранилище: мультимедиа, документы, и прочее.
• Внутреннее хранилище – файловое хранилище, доступное только для приложения.
• Сетевое хранилище – любой сторонний сервис для хранения данных, доступный по сети.
Помочь с выбором нужного хранилища поможет соответствующая страница документации.
#Architecture
• Shared Preferences – приватные примитивные данные в виде ключ-значение.
• SQLite – структурированные данные в приватной базе данных.
• Внешнее хранилище – общедоступное файловое хранилище: мультимедиа, документы, и прочее.
• Внутреннее хранилище – файловое хранилище, доступное только для приложения.
• Сетевое хранилище – любой сторонний сервис для хранения данных, доступный по сети.
Помочь с выбором нужного хранилища поможет соответствующая страница документации.
#Architecture
Какова структура Android-проекта?
В проекте обычно присутствуют следующие файлы и директории:
•
•
•
• Файл
•
•
•
•
•
•
•
•
•
•
#System
В проекте обычно присутствуют следующие файлы и директории:
•
AndroidManifest.xml
– определение компонентов и требуемых возможностей девайса для приложения.•
build.gradle
– файлы конфигурации сборки для всего приложения и отдельных модулей.•
src
– исходный код классов и ресурсы проекта.• Файл
.R
– сгенерированный на этапе компиляции перечень всех ресурсов проекта.•
assets
– файлы, которые должны попасть в .apk как есть, без изменений.•
res/drawable
– директория для картинок (drawable-объектов).•
res/layout
– директория для файлов которые определяют UI приложения.•
res/values
– директория для различных XML-файлов с простыми ресурсами, такими как строки, цвета и числа. •
res/mipmap
– иконки для launcher-а разных разрешений.•
res/menu
– XML с определениями разных меню.•
res/font
– шрифты.•
res/xml
– XML файлы, доступные через Resources.getXML()
.•
res/raw
– различные файлы, доступные в виде потоков данных через Resources.openRawResource()
.•
res/anim, res/animator
– анимации.#System
Назовите три основных применения интентов
1. Запустить активити.
2. Запустить сервис. Можно запустить сервис для выполнения единичной операции, передав
3. Доставить броадкаст. Для отправки броадкаст-ивента в другие приложения интент передается в
#Intent
1. Запустить активити.
Intent
передается в метод startActivity()
явно, либо разрешается с помощью механизма Intent Resolution.2. Запустить сервис. Можно запустить сервис для выполнения единичной операции, передав
Intent
в startService()
.3. Доставить броадкаст. Для отправки броадкаст-ивента в другие приложения интент передается в
sendBroadcast()
, sendOrderedBroadcast()
, или sendStickyBroadcast()
.#Intent
Назовите два способа очистить back stack при создании Activity
Флаг интента
Другой вариант –
#Intent
#Activity
Флаг интента
FLAG_ACTIVITY_CLEAR_TASK
используется для того, чтобы очистить все активити таска. Activity, запущенная таким интентом становится новым корнем пустого бэкстека. Этот флаг обязан быть использованным вместе с FLAG_ACTIVITY_NEW_TASK
.Другой вариант –
FLAG_ACTIVITY_CLEAR_TOP
. Разница в том, что если этот флаг задан, а в таск листе существует старый экземпляр данной активити, все другие активити будут удалены, а корнем станет тот старый экземпляр. Использовать при этом FLAG_ACTIVITY_NEW_TASK
не обязательно, но рекомендуется.#Intent
#Activity
Из каких базовых компонент состоит приложение?
Базовые компоненты андроид приложения: Activity, Service, BroadcastReceiver, ContentProvider. Каждый из базовых компонент объявляется в андроид манифесте и может являться точкой входа в приложение.
Activity представляет UI и функциональность, видимые пользователю.
Service используется для исполнения долгих операций, которые не требуют взаимодействия с пользователем.
BroadcastReceiver принимает и обрабатывает броадкаст ивенты, отправленные внутри приложения или из других приложений.
ContentProvider используется для обмена данными с другими приложениями.
Каждый из компонентов подробнее рассмотрим в будущем.
#Components
Базовые компоненты андроид приложения: Activity, Service, BroadcastReceiver, ContentProvider. Каждый из базовых компонент объявляется в андроид манифесте и может являться точкой входа в приложение.
Activity представляет UI и функциональность, видимые пользователю.
Service используется для исполнения долгих операций, которые не требуют взаимодействия с пользователем.
BroadcastReceiver принимает и обрабатывает броадкаст ивенты, отправленные внутри приложения или из других приложений.
ContentProvider используется для обмена данными с другими приложениями.
Каждый из компонентов подробнее рассмотрим в будущем.
#Components
Может ли приложение быть запущено в нескольких процессах?
Короткий ответ – Да.
Но для начала давайте разберемся чем процесс отличается от потока.
Процесс – это сущность на уровне ОС. Каждая программа может быть запущена в одном или нескольких процессах.
Поток – это сущность на уровне Runtime Environment.
Программа может выполняться в нескольких процессах. В каждом из процессов может быть создано несколько потоков (Java Threads).
Вернемся к андроиду. В предыдущем посте мы рассмотрели базовые компоненты и узнали, что каждый из компонентов может быть точкой входа в приложение. По умолчанию компоненты приложения работают в дефолтном процессе, но каждый из компонентов
Важно: При старте нового процесса создается инстанс приложения и снова вызывается
Подробнее про процессы и треды читайте в документации.
#System
Короткий ответ – Да.
Но для начала давайте разберемся чем процесс отличается от потока.
Процесс – это сущность на уровне ОС. Каждая программа может быть запущена в одном или нескольких процессах.
Поток – это сущность на уровне Runtime Environment.
Программа может выполняться в нескольких процессах. В каждом из процессов может быть создано несколько потоков (Java Threads).
Вернемся к андроиду. В предыдущем посте мы рассмотрели базовые компоненты и узнали, что каждый из компонентов может быть точкой входа в приложение. По умолчанию компоненты приложения работают в дефолтном процессе, но каждый из компонентов
<activity>
, <service>
, <receiver>
, <provider>
может иметь поле android:process="<name>"
в андроид манифесте. Кастомное значение этого поля явно говорит системе в каком процессе будет работать компонент.Важно: При старте нового процесса создается инстанс приложения и снова вызывается
Application.onCreate()
. Если в этом методе вы инициализируете модули или библиотеки, которые используются только в главном процессе, то не забывайте проверять, в каком процессе вы находитесь в момент инициализации.Подробнее про процессы и треды читайте в документации.
#System
Приоритеты процессов
Процессы делятся по приоритету на 4 вида, в порядке убывания:
1. Видимый активный процесс (Foreground process). В этом процессе работает приложение, с которым взаимодействует пользователь. Процесс находится в этом состоянии в следующих случаях:
-
- Во время выполнения
- Запущен
2. Видимый процесс. Пользователь знает о приложении, запущенном в этом процессе, но не взаимодействует с ним:
-
-
-
3. Background Service. Процесс с сервисом, запущенным командой startService().
4. Закэшированный процесс. К ним относятся пустые процессы, используемые при старте приложений, и процессы, в которых все активити в
Система убивает процессы в порядке возрастания их приоритета для восстановления ресурсов. Подробнее
#Lifecycle
#System
Процессы делятся по приоритету на 4 вида, в порядке убывания:
1. Видимый активный процесс (Foreground process). В этом процессе работает приложение, с которым взаимодействует пользователь. Процесс находится в этом состоянии в следующих случаях:
-
Activity
, у которой вызван onResume()
, но еще не вызван onPause()
- Во время выполнения
BroadcastReceiver.onReceive()
- Запущен
Service
и выполняется один из колбэков: onCreate()
, onStart()
, onDestroy()
2. Видимый процесс. Пользователь знает о приложении, запущенном в этом процессе, но не взаимодействует с ним:
-
Activity
у которой вызван onPause()
, но еще не вызван onStop()
.-
Service
, который запущен через Service.startForeground(). В этом случае пользователь видит нотификацию, связанную с сервисом.-
Service
, выполняющий функцию, о которой пользователь осведомлен. Например input method service.3. Background Service. Процесс с сервисом, запущенным командой startService().
4. Закэшированный процесс. К ним относятся пустые процессы, используемые при старте приложений, и процессы, в которых все активити в
onStop()
состоянии.Система убивает процессы в порядке возрастания их приоритета для восстановления ресурсов. Подробнее
#Lifecycle
#System
Activity: Что такое и как запустить?
Activity – основной компонент в андроиде. Активити – это экран, то что видит и с чем взаимодействует пользователь. Может содержать несколько View и фрагментов. Так же как и другие базовые компоненты, может быть точкой входа в приложение.
Активити с MAIN Intent Filter в манифесте запускается при старте приложения, когда пользователь кликает на иконку приложения.
#Activity
#Components
Activity – основной компонент в андроиде. Активити – это экран, то что видит и с чем взаимодействует пользователь. Может содержать несколько View и фрагментов. Так же как и другие базовые компоненты, может быть точкой входа в приложение.
Активити с MAIN Intent Filter в манифесте запускается при старте приложения, когда пользователь кликает на иконку приложения.
#Activity
#Components
Activity: Жизненный цикл
Жизненный цикл активити состоит из шести основных коллбэков, вызываемых системой. В порядке вызова:
onCreate() вызывается когда активити создается. В
onStart() вызывается когда активити отрисована и видима пользователю.
onResume() вызывается перед тем как активити станет доступна для взаимодействия с пользователем.
onPause() – метод симметричный
onStop() – метод симметричный
onDestroy() – метод симметричный
Несколько примеров:
1. Пользователь жмет Home. В этом случае активити больше не видна, поэтому вызываются
2. Пользователь переходит на другую активити внутри приложения (реализуется вызовом
3. Вызов
4. Пользователь поворачивает телефон и ориентация активити меняется. Активити пересоздается и вызываются коллбеки
Это базовые методы активити. Более подробно они описаны в документации.
В полный жизненный цикл также входят
#Activity
#Lifecycle
Жизненный цикл активити состоит из шести основных коллбэков, вызываемых системой. В порядке вызова:
onCreate()
, onStart()
, onResume()
, onPause()
, onStop()
, onDestroy()
.onCreate() вызывается когда активити создается. В
onCreate()
вы должны вызвать метод setContentView().onStart() вызывается когда активити отрисована и видима пользователю.
onResume() вызывается перед тем как активити станет доступна для взаимодействия с пользователем.
onPause() – метод симметричный
onResume()
. Пользователь больше не может взаимодействовать с активити, но активити частично видна пользователю. В этом состоянии UI активити может изменяться.onStop() – метод симметричный
onStart()
. Вызывается, когда активити больше не видна пользователю.onDestroy() – метод симметричный
onCreate()
. Вызывается перед тем, как активити будет уничтожена системой.Несколько примеров:
1. Пользователь жмет Home. В этом случае активити больше не видна, поэтому вызываются
onPause()
, onStop()
. Пользователь открывает приложение снова - onStart()
, onResume()
.2. Пользователь переходит на другую активити внутри приложения (реализуется вызовом
startActivity()
) – onPause()
, onStop()
. Пользователь возвращается на предыдущую активити – onStart()
, onResume()
.3. Вызов
finish()
– onPause()
, onStop()
, onDestroy()
. Когда пользователь перейдет на эту активити снова, она будет создана с нуля без сохранения состояния.4. Пользователь поворачивает телефон и ориентация активити меняется. Активити пересоздается и вызываются коллбеки
onPause()
, onStop()
, onDestroy()
, onCreate()
, onStart()
, onResume()
с сохранением состояния.Это базовые методы активити. Более подробно они описаны в документации.
В полный жизненный цикл также входят
onRestart()
, onSaveInstanceState()
, onRestoreInstanceState()
, onNewIntent()
и другие методы, которые разберем в будущем.#Activity
#Lifecycle
Activity: Как пережить поворот экрана?
При повороте экрана активити уничтожается и создается заново. Вызываются коллбэки
Чтобы сохранить состояние активити, вы должны переопределить метод onSaveInstanceState() и положить данные в Bundle.
При реинициализации активити,
Система вызывает
onSaveInstanceState() вызывается после
onRestoreInstanceState() вызывается после
#Activity
#Lifecycle
#State
При повороте экрана активити уничтожается и создается заново. Вызываются коллбэки
onPause()
, onStop()
, onSaveInstanceState()
, onDestroy()
– onCreate()
, onStart()
, onRestoreInstanceState()
, onResume()
.Чтобы сохранить состояние активити, вы должны переопределить метод onSaveInstanceState() и положить данные в Bundle.
При реинициализации активити,
Bundle
с сохраненным состоянием передается в onCreate()
и в onRestoreInstanceState().Система вызывает
onSaveInstanceState()
и onRestoreInstanceState()
только в том случае, когда необходимо сохранить состояние, например при повороте экрана или при убийстве активити для освобождения памяти. Данные коллбэки не вызываются, если пользователь выходит из активити нажав Back или если активити убивается вызовом finish()
.onSaveInstanceState() вызывается после
onStop()
на версии API ≥ 28. На API < 28 этот коллбэк вызывается перед onStop()
и нет гарантий до или после onPause()
.onRestoreInstanceState() вызывается после
onStart()
.#Activity
#Lifecycle
#State