Расскажите про реализацию метода View.onDraw()
Метод onDraw() отвечает за саму отрисовку View на экране пользователя. На вход она получает объект Canvas — холст. На канвасе можно рисовать все что угодно: 2D графику, текст, обычный и стилизованный, геометрические фигуры и много чего еще. Для рисования на канвасе используется объект Paint — кисточка. Она определяет как именно нужно рисовать то, что вы […]
Смотреть урок →Чем отличаются apply() и commit() в SharedPreferences?
Схема изменения данных, сохраненных в SharedPreferences выглядит как-то так: Так же есть вот такой вариант, покороче: В первом случае был использован apply(), во втором же commit() Разница между этими двумя методами состоит в том, что commit() выполняется в главном потоке и по окончанию своего исполнения возвращает boolean переменную, true — если все успешно сохранилось и […]
Смотреть урок →Чем отличаются Preference и SharedPreferences?
Несмотря на схожие названия, это разные вещи, хоть и связанные. SharedPreferences — это класс, необходимый для хранения данных. Он позволяет хранить пары ключ — значение, где ключом выступает какая-то строка, а значения могут быть любым примитивом/строкой. Данный способ хранения данных обычно используют, когда необходимо сохранить небольшое количество данных, в случае же, если надо хранить большой […]
Смотреть урок →В чем разница между build type, flavor и build variant?
Build Type — тип сборки. Он используется чтобы задать настройки сборки. По умолчанию Android Studio создает 2 типа сборки, debug и release, но в файле build.gradle прописан только один. Тип сборки debug включает в себя полезные инструменты для отладки, а также он подписан своим ключом. Тип сборки release же включает в себя оптимизацию кода через […]
Смотреть урок →Способы выполнения кода в UI потоке. Можно ли обновлять View не из UI потока?
Обращаться к каким-нибудь элементам View не из UI потока нельзя, поэтому UI поток так и назван, что только он может обновлять вьюхи. Если попытаться обновить вьюхи не из UI потока, то вылетит CalledFromWrongThreadException. Есть несколько способов исполнить кусок кода в UI потоке. Использовать метод activity.runOnUiThread(Runnable). Этот метод выполняет кусок кода, который записан в метод run() […]
Смотреть урок →Сколько main activity может содержать AndroidManifest?
Main activity — это активити, которая в своем интент фильтре объявила action main и category launcher, как здесь: Action main означает, что данная активити является точкой входа в приложение, точек входа может быть несколько и у нескольких активити action main может быть объявлена в интент фильтре. В то же время category launcher означает, что для […]
Смотреть урок →Intent resolution неявных интентов.
Intent Resolution — механизм поиска нужного компонента для вызова по неявному интенту. Когда вы используете явный интент, вы четко прописываете какой именно компонент запустить, используя же неявный интент, вы не знаете какой именно компонент будет запущен, вы знаете только что он должен уметь делать. Когда вы используете неявный интент, система Android сама находит соответствующий компонент […]
Смотреть урок →Особенности отличия Bundle от Intent
Bundle с английского означает пакет/сверток. Этот класс используется для передачи данных между базовыми компонентами, например между активити или между фрагментами. Так же он используется для сохранения состояния активити при изменениях конфигурации. В этом классе реализованы методы get() и put() для всех примитивов, строк, а также для Parcelable и Serializable. Intent же означает намерение. Этот класс […]
Смотреть урок →Расскажите про Cursor
Cursor — возвращаемый методом query() тип. Объект данного класса представляет собой табличку, состоящую из строк и столбцов, где столбцы представляют собой выбранные поля в записи бд, а строки это и есть сами записи. Таким образом, Cursor, который возвращается методом query(), в качестве столбцов содержит те столбцы, которые были указаны на входе в метод, а в […]
Смотреть урок →Особенности работы с данными через ContentResolver
ContentResolver имеет методы, одноименные методам ContentProvider, и выполняющие CRUD функции (create, read, update, delete). Вот список данных методов: insert() — соответствует функции create. Создает новую запись в провайдере и возвращает URI данной записи. Данные для новой записи помещаются в объект ContentValues как пары столбец — значение. query() — соответствует функции read. С английского переводится как […]
Смотреть урок →Системные контент-провайдеры в Android
Встроенных провайдеров довольно много, все их перечислять здесь будет проблематично. Но все встроенные провайдеры лежат в папке android.provider Android SDK, так что при желании можно будет все их посмотреть и изучить. Ну а к списку основных провайдеров относятся (здесь перечислены не все): Contacts. Провайдер контактов, но данный класс считается устаревшим начиная с версии API 5, […]
Смотреть урок →Для чего предназначен ContentProvider?
ContentProvider с английского переводится как “поставщик контента”. Это абстрактный класс и поэтому чтобы создать свой провайдер необходимо создать наследника этого класса. Бывают ситуации, когда одно приложение хочет использовать данные другого приложения. Но приложения не могут работать с чужими базами данных. Поэтому для того, чтобы позволить одному приложению использовать данные другого, используется ContentProvider. Можно использовать ContentProvider […]
Смотреть урок →Расскажите про утечку Activity / Context
Утечка активити/контекста в Android это утечка памяти, вызванная тем что активити/контекст уже уничтожены, но на них все еще есть внешние ссылки(например в статик переменной). В итоге сборщик мусора не может удалить эту активити/контекст, хотя он по сути уже бесполезен, тк onDestroy() была вызвана. И так как активити и контекст это тяжелые объекты, которые занимают много […]
Смотреть урок →Ограничения на BroadcastReceiver в Android 8.0
Начиная с версии Android 8.0 (API level 26) система начала накладывать дополнительные ограничения на ресиверы, объявленные статически через AndroidManifest.xml С этой версии Андроид больше не получится использовать статически объявленные ресиверы для получения неявных броадкастов (т.е броадкастов, которые предназначены не именно для твоего приложения). Все еще можно использовать динамически объявленные (зарегистрированные через context.registerReceiver()) ресиверы для получения […]
Смотреть урок →Расскажите про sticky broadcast
Sticky broadcast — это броадкаст, который сохраняется системой после отправки. Таким образом после того как вы отправили такой броадкаст, ресивер может его получить при регистрации, через возвращающее значение метода registerReceiver() (registerReceiver() возвращает Intent). В остальном это точно такой же броадкаст как и броадкаст, отправленный используя sendBroadcast() Стоит учитывать, что у sticky broadcast’ов есть проблемы с […]
Смотреть урок →Способы отправки броадкастов в Android
Всего существует три способа отправить броадкаст. Использовать метод sendOrderedBroadcast(). При отправке броадкаста таким способом, он отправится последовательно по всем ресиверам, не больше чем к одному ресиверу одновременно. Причем каждый из ресиверов может либо распространить броадкаст дальше, либо не отправлять его остальным ресиверам. Приоритет, в котором ресиверы получают броадкаст настраивается параметром priority объекта intent-filter. Если же […]
Смотреть урок →Длительные операции в методе onReceive(). В чем их особенность?
Выполнять длительные операции в методе onReceive() не стоит. Дело в том, что если приложение не запущено, а ресивер принял какой-то броадкаст (это был статически зарегистрированный ресивер), то система запустит приложение (при этом не запустит активити, то есть приложение будет работать в фоне) и вызовет метод onReceive() вашего ресивера. Данный метод исполняется на главном потоке и […]
Смотреть урок →Основные методы жизненного цикла сервиса
Самыми важными методами жизненного цикла сервиса являются: 1. onStartCommand() Данный метод вызывается после того, как другой компонент (например активити) вызвал метод startService(). Когда данный метод был вызван, сервис запускается и живет до тех пор, пока в нем не будет вызван метод stopSelf(), либо же в другом компоненте не будет вызван метод stopService(). Если же сервис […]
Смотреть урок →Назовите ограничения по фоновым сервисам в Android 8.0?
Для начала разберемся с разницей между foreground (не фоновое) и background (фоновое) приложениями. Приложение считается foreground если выполняется хотя бы один из этих пунктов: У приложения запущен foreground сервис У приложения видима какая-либо активити К приложению подключено другое foreground приложение (например к сервису или к провайдеру данного приложения) Так вот, начиная с Android 8.0 система […]
Смотреть урок →Где и как работает Service?
Несмотря на то, что сервисы предназначены для выполнения фоновых операций, они не работают в фоновом потоке. Не стоит путать фоновую операцию с фоновым потоком. Сервисы предназначены для того, чтобы выполнять какую-либо операцию даже, когда приложение не запущено и пользователь с ним не взаимодействует. Так как сервисы работают в UI потоке, то, для выполнения блокирующих потоков, […]
Смотреть урок →