Устанавливаем одновременно несколько версий приложения
#beginners
Многие разработчики используют свои телефоны в качестве устройств для тестирования и разработки. В целом, в этом нет ничего плохого, однако есть одна проблема: по умолчанию вы можете иметь только одну версию приложения на устройстве.
Ситуация усугубляется, если вы хотите держать одновременно debug, test и release версии.
К счастью, есть достаточно простое решение, которое позволит иметь сколько угодно версий одного и того же приложения на одном устройстве. Вот вам инструкция, как это сделать:
🔸настройте отдельные
🔸добавьте
🔸добавьте новое название test-сборки. В Android Studio добавьте новый xml-файл для строк, который поместите в папку test/res/values. Там уже сделайте нужное вам название, а название релизного билда переместите в release/res/values.
🔸добавьте новую иконку по такому же алгоритму. Вам нужно добавить её в test/res, Android Studio может всё переместить за вас.
🔸зарегистрируйте новое приложение в проекте для Firebase и поправьте файл google-services.json, который вам обновит сам Firebase.
На этом всё, проблема нескольких сборок решена. Детальнее можно почитать тут.
#beginners
Многие разработчики используют свои телефоны в качестве устройств для тестирования и разработки. В целом, в этом нет ничего плохого, однако есть одна проблема: по умолчанию вы можете иметь только одну версию приложения на устройстве.
Ситуация усугубляется, если вы хотите держать одновременно debug, test и release версии.
К счастью, есть достаточно простое решение, которое позволит иметь сколько угодно версий одного и того же приложения на одном устройстве. Вот вам инструкция, как это сделать:
🔸настройте отдельные
buildTypes. Сделаем test и release;🔸добавьте
applicationIdSuffix для test-версии. Например, _test;🔸добавьте новое название test-сборки. В Android Studio добавьте новый xml-файл для строк, который поместите в папку test/res/values. Там уже сделайте нужное вам название, а название релизного билда переместите в release/res/values.
🔸добавьте новую иконку по такому же алгоритму. Вам нужно добавить её в test/res, Android Studio может всё переместить за вас.
🔸зарегистрируйте новое приложение в проекте для Firebase и поправьте файл google-services.json, который вам обновит сам Firebase.
На этом всё, проблема нескольких сборок решена. Детальнее можно почитать тут.
Ежегодный опрос команд российской разработки
В этом году начался ежегодный, пятый опрос про отечественные мобильные команды разработки. Из него можно узнать:
📖 откуда мобильщики получают новые знания;
💪 какие команды мобильной разработки самые сильные;
🌟 в каких компаниях мобильные разработчики хотят работать больше всего.
Вот результаты прошлого года, а поучаствовать в опросе этого года можно тут. Опрос займёт не больше минуты.
Не забудьте выбрать на одном из шагов также канал Android Live, для меня это очень важно 🤝.
В этом году начался ежегодный, пятый опрос про отечественные мобильные команды разработки. Из него можно узнать:
📖 откуда мобильщики получают новые знания;
💪 какие команды мобильной разработки самые сильные;
🌟 в каких компаниях мобильные разработчики хотят работать больше всего.
Вот результаты прошлого года, а поучаствовать в опросе этого года можно тут. Опрос займёт не больше минуты.
Не забудьте выбрать на одном из шагов также канал Android Live, для меня это очень важно 🤝.
Как измерить и оптимизировать размера Bitmap
#view #library
Если мы видим падение с
Есть хорошая статья о том, как понять, что что-то не так с изображениями.
1️⃣ Первым шагом должно быть определение размера bitmap. Сделать это можно при помощи profiler. Автор также советует использовать устройства с Android 7.1 и ниже, так как там можно увидеть preview изображения.
2️⃣ Далее стоит посмотреть на качество вашего изображения и на размер
3️⃣ Ну и напоследок стоит обратить внимание на профиль для загрузки изображений. По умолчанию может быть AGRB_8888, который использует 4 байта для каждого из пикселей. Но для большинства задач достаточно RGB_565, который использует в 2 раза меньше байтов. Да, качество изображений получается хуже, и нет поддержки прозрачности. Но для многих задач достаточно и такого качества.
#view #library
Если мы видим падение с
OutOfMemory, то чаще всего думаем про утечки, которые есть в приложении. Однако, подобная ошибка не всегда вызвана утечками памяти. Одной из причин может быть чрезмерное использование памяти нашим приложением, из-за неправильной загрузки изображений.Есть хорошая статья о том, как понять, что что-то не так с изображениями.
1️⃣ Первым шагом должно быть определение размера bitmap. Сделать это можно при помощи profiler. Автор также советует использовать устройства с Android 7.1 и ниже, так как там можно увидеть preview изображения.
2️⃣ Далее стоит посмотреть на качество вашего изображения и на размер
ImageView, в который вы его загружаете. Если оно меньше, то полезно будет использовать методы fit() и centerInside() для Glide и Picasso.3️⃣ Ну и напоследок стоит обратить внимание на профиль для загрузки изображений. По умолчанию может быть AGRB_8888, который использует 4 байта для каждого из пикселей. Но для большинства задач достаточно RGB_565, который использует в 2 раза меньше байтов. Да, качество изображений получается хуже, и нет поддержки прозрачности. Но для многих задач достаточно и такого качества.
onActivityCreated() во Fragment — deprecated
#fragment
Наверное, это уже не новость, но кто знает, может вы, как и я, пропустили её.
Стоило мне обновить версии библиотек в основном проекте, как я увидел, что метод
Что это вообще за метод, и почему он стал теперь deprecated?
Этот метод существует по той причине, что фрагменты не могут существовать как независимый компонент. Для их работы и отображения необходим или контейнер в
Но технологии развиваются и приходит переосмысление некоторым вещам. Не кажется ли вам странным, что один класс имеет метод в своём жизненнном цикле о том, что был создан его родительский класс? Вот и разработчики Google посчитали это странным и решили сделать
Сейчас есть две рекомендации:
1️⃣ Все операции, связанные со
2️⃣ Если вам нужно получить информацию о том, что
В целом, интересно, как будет вести себя
#fragment
Наверное, это уже не новость, но кто знает, может вы, как и я, пропустили её.
Стоило мне обновить версии библиотек в основном проекте, как я увидел, что метод
onActivityCreated() стал deprecated.Что это вообще за метод, и почему он стал теперь deprecated?
Этот метод существует по той причине, что фрагменты не могут существовать как независимый компонент. Для их работы и отображения необходим или контейнер в
Activity, или родительский Fragment. Для того, чтобы сообщить, что Activity был создан и был создан этот метод. Но технологии развиваются и приходит переосмысление некоторым вещам. Не кажется ли вам странным, что один класс имеет метод в своём жизненнном цикле о том, что был создан его родительский класс? Вот и разработчики Google посчитали это странным и решили сделать
Fragment менее зависимым от родительского компонента и убрать этот метод. Сейчас есть две рекомендации:
1️⃣ Все операции, связанные со
View во Fragment нужно делать в onViewCreated(). 2️⃣ Если вам нужно получить информацию о том, что
Activity была создана, то можно зарегистрировать LifeCycleObserver в методе onAttach() и удалён после вызова метода onCreate(). Как по мне, звучит как костыль.В целом, интересно, как будет вести себя
Fragment дальше, если его делают менее зависимым от других частей приложения. 🤔Дополнительная настройка Timber
#library
Timber довольная популярная библиотека для логирования. Она включает в себя не очень много дополнительных методов, однако значительно облегчает ввод логов, по сравнению со стандартными средствами.
Есть вариант использовать официальную библиотеку от JakeWharton, но мне больше по душе fork, где добавили чуть больше возможностей для работы с Kotlin.
Пара полезных настроек, которые улучшат взаимодействие с библиотекой и качеством логов:
1️⃣ Добавьте глобальный тег в настройках, чтобы было проще увидеть логи из вашего приложения. Сделать это можно при помощи переопределения метода
2️⃣ Добавьте название метода, из которого было показано данное сообщение. Для этого нужно переопределить метод
Кроме этого, можно добавить сюда же и номер линии из которой было вызвано сообщение.
Больше кода об этих настройках можно найти тут.
#library
Timber довольная популярная библиотека для логирования. Она включает в себя не очень много дополнительных методов, однако значительно облегчает ввод логов, по сравнению со стандартными средствами.
Есть вариант использовать официальную библиотеку от JakeWharton, но мне больше по душе fork, где добавили чуть больше возможностей для работы с Kotlin.
Пара полезных настроек, которые улучшат взаимодействие с библиотекой и качеством логов:
1️⃣ Добавьте глобальный тег в настройках, чтобы было проще увидеть логи из вашего приложения. Сделать это можно при помощи переопределения метода
log в DebugTree, вызвав super.log(priority, "global_tag_$tag", message, t).2️⃣ Добавьте название метода, из которого было показано данное сообщение. Для этого нужно переопределить метод
createStackElementTag в том же DebugTree, отформатировав показ сообщения. Кроме этого, можно добавить сюда же и номер линии из которой было вызвано сообщение.
Больше кода об этих настройках можно найти тут.
Flutter vs Kotlin Multiplatform Mobile
#youtube
Напоминаю всем про сегодняшний стрим, где будем обсуждать плюсы и минусы каждого из фреймворков. Больше деталей тут.
Трансляция пройдёт онлайн, 24 марта в 18:00 по МСК, как всегда на Youtube-канале AndroidLive. Ссылка на трансляцию тут, задавайте свои вопросы и темы для сравнения тут.
До встречи!🤟
#youtube
Напоминаю всем про сегодняшний стрим, где будем обсуждать плюсы и минусы каждого из фреймворков. Больше деталей тут.
Трансляция пройдёт онлайн, 24 марта в 18:00 по МСК, как всегда на Youtube-канале AndroidLive. Ссылка на трансляцию тут, задавайте свои вопросы и темы для сравнения тут.
До встречи!🤟
Новое API для Flow и UI-слоя
#flow #jetpack
Пару дней назад Google выпустили обновление для API
Если говорить о текущем состоянии, то, в целом, мы уже можем использовать
Теперь у нас есть три новых метода:
🔸 LifecycleOwner.addRepeatingJob — принимает
🔸Lifecycle.repeatOnLifecycle — аналогичная функция, но только для
🔸Flow.flowWithLifecycle — этот API использует предыдущую функцию под капотом и также закрывает «продьюсера» в момент противоположного состояния жизненного цикла. Кроме этого, данную фукнцию можно встроить напрямую в целочку вызова
В целом, в статье упоминается то, что теперь можно полностью эмитировать поведение
Кроме этого, если вам это нужно, добавили поддержку data binding для
#flow #jetpack
Пару дней назад Google выпустили обновление для API
Flow, где заметно улучшили его взаимодействие с UI-слоем. Если говорить о текущем состоянии, то, в целом, мы уже можем использовать
Flow и отказаться от LiveData. Правда, есть одно замечание: может быть не безопасно подписываться в UI-слое на холодный Flow, если мы вручную не можем отменить задачу, которая им выполняется. В качестве примера в статье приводится обновление локации пользователя и возможное текущее решение.Теперь у нас есть три новых метода:
🔸 LifecycleOwner.addRepeatingJob — принимает
Lifecycle.State в качестве параметра и используется для автоматического создания и старта новой корутины и отменяет её, когда состояние достигнет противоположного значения.🔸Lifecycle.repeatOnLifecycle — аналогичная функция, но только для
Lifecycle. 🔸Flow.flowWithLifecycle — этот API использует предыдущую функцию под капотом и также закрывает «продьюсера» в момент противоположного состояния жизненного цикла. Кроме этого, данную фукнцию можно встроить напрямую в целочку вызова
Flow, что делает вызов более лаконичным. Важно помнить, что эта функция работает по аналогии с Flow.flowOn, которая затрагивает только цепочку, которая выше неё и добавляет буфер для предотвращения backpressure.В целом, в статье упоминается то, что теперь можно полностью эмитировать поведение
LiveData и использовать Flow в приложениях, где вы хотите использовать только Kotlin API. Это здорово, но пока API находится в alpha-версии и стоит тащить его к себе аккуратно.Кроме этого, если вам это нужно, добавили поддержку data binding для
Flow. Детали тут.Countdown Timer с Jetpack Compose
#jetpack #compose
Многие знают о том, что сразу после выхода beta-версии Jetpack Compose Google анонсировали Android Dev Challenge. Это возможность попробовать новую технологию, поучаствовать в конкурсе и выиграть призы.
Для тех, кто не мог участвовать (а разработчики из России не могли 😑) есть возможность посмотреть на хороший пример приложения со второй недели этого конкурса.
В задачу входило написание таймера, где UI должен полностью быть на Compose. Можно ознакомиться с такими понятиями, как State, Composition, Initial composition, rememberSaveable и т.д. Ну и да, много когда на Compose, что не может не радовать.
Ссылка на статью тут, а код можно найти тут
#jetpack #compose
Многие знают о том, что сразу после выхода beta-версии Jetpack Compose Google анонсировали Android Dev Challenge. Это возможность попробовать новую технологию, поучаствовать в конкурсе и выиграть призы.
Для тех, кто не мог участвовать (а разработчики из России не могли 😑) есть возможность посмотреть на хороший пример приложения со второй недели этого конкурса.
В задачу входило написание таймера, где UI должен полностью быть на Compose. Можно ознакомиться с такими понятиями, как State, Composition, Initial composition, rememberSaveable и т.д. Ну и да, много когда на Compose, что не может не радовать.
Ссылка на статью тут, а код можно найти тут
Emoji под капотом
#view
Любопытная статья о том, как работают emoji под капотом.
По сути emoji — это стандартные Unicode-символы, которые ведут себя так же, как и обычные буквы: вы можете их вводить с клавиатуры, копировать, выделять и т.д.
Интересно, что это также bitmap font, где каждый символ — это или растровое или векторное изображение. Все зависит от операционной системы – на Android это битмапы размером 128×128. Вот главная причина, почему emoji выглядят по-разному на различных устройствах. Ну и некоторые приложения или вендоры переопределяют шрифты, чтобы отрисовать их по-своему.
В статье автор также рассматривает ситуации:
🔸когда emoji пересекаются с уже существующими пиктограммами;
🔸почему все emoji выглядят одинаково при любом выбранном шрифте;
🔸какие проблемы могут быть при нахождении длины строки и emoji;
🔸как работает модификация тона кожи;
🔸как можно комбинировать несколько emoji в одну и многое другое.
Ссылка на статью тут. Лично мне было интересно узнать столько новых деталей про такой распространённый инструмент. 🙃
#view
Любопытная статья о том, как работают emoji под капотом.
По сути emoji — это стандартные Unicode-символы, которые ведут себя так же, как и обычные буквы: вы можете их вводить с клавиатуры, копировать, выделять и т.д.
Интересно, что это также bitmap font, где каждый символ — это или растровое или векторное изображение. Все зависит от операционной системы – на Android это битмапы размером 128×128. Вот главная причина, почему emoji выглядят по-разному на различных устройствах. Ну и некоторые приложения или вендоры переопределяют шрифты, чтобы отрисовать их по-своему.
В статье автор также рассматривает ситуации:
🔸когда emoji пересекаются с уже существующими пиктограммами;
🔸почему все emoji выглядят одинаково при любом выбранном шрифте;
🔸какие проблемы могут быть при нахождении длины строки и emoji;
🔸как работает модификация тона кожи;
🔸как можно комбинировать несколько emoji в одну и многое другое.
Ссылка на статью тут. Лично мне было интересно узнать столько новых деталей про такой распространённый инструмент. 🙃
Исследование поведения подключённых библиотек
#gradle #security
Большинство разработчиков используют сторонние библиотеки, так как они часто предоставляют оттестированную и готовую фукнциональность, которую будет очень тяжело сделать самостоятельно. Но при этом, мы не часто задумываемся о том, что включают в себя эти библиотеки и нет ли в них какой-то скрытой от нас функциональности, которую мы бы не хотели видеть у себя в приложении.
Есть пара советов, которые помогут исследовать сторонние библиотеки:
0️⃣ Merged manifest view. Функциональность позволяет сделать общий AndroidManifest из всех подключённых в проект библиотек. Таким образом вы сможете посмотреть, какие дополнительные сервисы, разрешения,
Для этого нужно кликнуть Merged Manifest внизу открытого AndroidManifest-файла. Обязательно посмотрите, нет ли каких-то скрытых запросов разрешений, и если нет возможности отказаться от библиотеки, то выключите их при помощи этого кода:
1️⃣ Просмотр зависимостей модуля. Эта штука поможет вам настроить транзитивные зависимости, а также проанализировать то, какие дополнительные штуки включает добавленная библиотека. Подробнее почитать можно тут.
2️⃣ Аудит доступа к данным. Достаточно новая фича, которая позволяет посмотреть использование приватных данных вашим приложением. Делается это при помощи
Я сам на практике не использовал, но выглядит интересно. Кроме того, можно зарегистрировать свой атрибут для приватной операции, который также будет попадать в этот callback. Детали тут.
А какие ещё методы исследования библиотек вы знаете?
#gradle #security
Большинство разработчиков используют сторонние библиотеки, так как они часто предоставляют оттестированную и готовую фукнциональность, которую будет очень тяжело сделать самостоятельно. Но при этом, мы не часто задумываемся о том, что включают в себя эти библиотеки и нет ли в них какой-то скрытой от нас функциональности, которую мы бы не хотели видеть у себя в приложении.
Есть пара советов, которые помогут исследовать сторонние библиотеки:
0️⃣ Merged manifest view. Функциональность позволяет сделать общий AndroidManifest из всех подключённых в проект библиотек. Таким образом вы сможете посмотреть, какие дополнительные сервисы, разрешения,
Activity и т.д. вносят ваши зависимости. Для этого нужно кликнуть Merged Manifest внизу открытого AndroidManifest-файла. Обязательно посмотрите, нет ли каких-то скрытых запросов разрешений, и если нет возможности отказаться от библиотеки, то выключите их при помощи этого кода:
<uses-permission android:name="SOME_PERMISSION"
tools:node="remove"/>1️⃣ Просмотр зависимостей модуля. Эта штука поможет вам настроить транзитивные зависимости, а также проанализировать то, какие дополнительные штуки включает добавленная библиотека. Подробнее почитать можно тут.
2️⃣ Аудит доступа к данным. Достаточно новая фича, которая позволяет посмотреть использование приватных данных вашим приложением. Делается это при помощи
AppOpsManager.OnOpNotedCallback, куда приходят методы с пометкой приватного доступа, например «share with friends». Я сам на практике не использовал, но выглядит интересно. Кроме того, можно зарегистрировать свой атрибут для приватной операции, который также будет попадать в этот callback. Детали тут.
А какие ещё методы исследования библиотек вы знаете?
Про PendingIntent
#interview
Отсюда мы сразу выносим две ключевые разницы:
🔹событие связано с будущим действием;
🔹это действие происходит от имени вашего приложения.
Область применения
🔸FLAG_IMMUTABLE — означает, что
🔸FLAG_MUTABLE — означает, что компонент внутри
🔸FLAG_UPDATE_CURRENT — означает, что необходимо обновить содержимое компонента без создания нового
🔸FLAG_ONE_SHOT — позволяет
🔸FLAG_CANCEL_CURRENT — закрывает существующий
Почитать детальнее о том, как использовать этот компонент в Android 12 можно тут.
#interview
PendingIntent — довольно важная часть приложений под Android, о которой мы часто забываем и не до конца понимаем, для чего она нужна. Так как с Android 12 у нас добавились изменения, связанные с работой с PendingIntent, давайте посмотрим, что это за класс, ну и поговорим про изменения. PendingIntent по сути — обёртка над обычным Intent, которая позволяет другому приложению выполнить какое-то действие в будущем от имени вашего приложения. Отсюда мы сразу выносим две ключевые разницы:
🔹событие связано с будущим действием;
🔹это действие происходит от имени вашего приложения.
Область применения
PendingIntent довольно обширна. Самые распространённые кейсы — это работа с AlarmManager и уведомлениями. Тут можно найти ещё пару кейсов, например при взаимодействии с получением результата от другого приложения.PendingIntent создаётся с флагами, которые влияют на его работу. 🔸FLAG_IMMUTABLE — означает, что
Intent внутри PendingIntent не может быть модифицирован другим приложением. Важно помнить, что приложение всегда может менять свои PendingIntent, даже если они неизменяемы для других приложений. До Android 12 все PendingIntent, созданные без этого флага были изменяемыми по умолчанию.🔸FLAG_MUTABLE — означает, что компонент внутри
PendingIntent может быть модифицирован другим приложением при помощи PendingIntent.send(). Флаг был добавлен в Android 12, и очень важно заполнять ComponentName при такой модификации. 🔸FLAG_UPDATE_CURRENT — означает, что необходимо обновить содержимое компонента без создания нового
PendingIntent. Если такого нет, то будет создан новый. 🔸FLAG_ONE_SHOT — позволяет
PendingIntent выполнять действие только один раз. 🔸FLAG_CANCEL_CURRENT — закрывает существующий
PendingIntent, что особенно важно, если вы хотите поменять приложение, на которое завязан ваш текущий PendingIntent. Почитать детальнее о том, как использовать этот компонент в Android 12 можно тут.
Старт в KMM
#kotlin #kmm #beginners
Коллеги из чата про KMM делают доку для погружения и ознакомления с этой технологией. Будет полезно всем, и тем кто ещё только собирается изучать технологию, и тем, кто уже в теме.
На ресурсе можно найти информацию:
🔹о том, почему и когда стоит выбирать KMM для проекта;
🔹как настроить окружение для разработки (особенно актуально для iOS-разработчиков);
🔹как написать первый проект;
🔹как работать с некоторыми из библиотек и многое другое.
Важно, что проект opensource и каждый может внести свой вклад в эту доку. Ссылка на сайт тут.
#kotlin #kmm #beginners
Коллеги из чата про KMM делают доку для погружения и ознакомления с этой технологией. Будет полезно всем, и тем кто ещё только собирается изучать технологию, и тем, кто уже в теме.
На ресурсе можно найти информацию:
🔹о том, почему и когда стоит выбирать KMM для проекта;
🔹как настроить окружение для разработки (особенно актуально для iOS-разработчиков);
🔹как написать первый проект;
🔹как работать с некоторыми из библиотек и многое другое.
Важно, что проект opensource и каждый может внести свой вклад в эту доку. Ссылка на сайт тут.
Паттерны проектирования в Android разработке
#design #patterns #beginners
Паттерны проектирования — очень полезная штука, которая позволяет решать возникающие задачи оптимальным и уже проверенным способом. Кроме того, что такие подходы делают код чистым и легко расширяемым, они дают возможность лёгкого освоения вашего кода другим разработчикам. Ведь можно просто назвать используемый вами паттерн.
Если вы хотите связать существующие паттерны с Android-разработкой, то есть отличная статья, которая разбирает основные паттерны и описывает примеры, которые есть в Android. Вот некоторые из шаблонов: Builder, DI, Singleton, Factory, Adapter, Facade, Observer и многие другие.
Ну и обильные примеры кода также весьма радуют. Ссылка на статью тут.
#design #patterns #beginners
Паттерны проектирования — очень полезная штука, которая позволяет решать возникающие задачи оптимальным и уже проверенным способом. Кроме того, что такие подходы делают код чистым и легко расширяемым, они дают возможность лёгкого освоения вашего кода другим разработчикам. Ведь можно просто назвать используемый вами паттерн.
Если вы хотите связать существующие паттерны с Android-разработкой, то есть отличная статья, которая разбирает основные паттерны и описывает примеры, которые есть в Android. Вот некоторые из шаблонов: Builder, DI, Singleton, Factory, Adapter, Facade, Observer и многие другие.
Ну и обильные примеры кода также весьма радуют. Ссылка на статью тут.
Google IO 2021
#conference
На этой неделе Google анонсировал даты конференции для Android-разработчиков — Google IO 2021. В этом году она пройдёт с 18—20 мая только онлайн, без возможности оффлайн участия.
Пока нет деталей о том, чего ждать на этой конфереции. Судя по всему, это будет анонс beta-версии Android 12 с более детальным рассказом о том, что он нам принесёт, релизом новых библиотек и подходов.
Уверен, что будет детально рассказано про Jetpack Compose и его статус, возможно он уже будет production ready.
Тут можно решить небольшой ребус, а тут зарегистрироваться на само мероприятие, оно полностью бесплатное.
Ну и вы узнаете обо всех новинках конфереции первыми, так как подписаны на Android Live, так что следите за обновлениями. 😉
А может быть у вас есть идеи особых меропрятий для канала Android Live, которые посвящены этой конференции?
Можете поделиться в комментариях.
#conference
На этой неделе Google анонсировал даты конференции для Android-разработчиков — Google IO 2021. В этом году она пройдёт с 18—20 мая только онлайн, без возможности оффлайн участия.
Пока нет деталей о том, чего ждать на этой конфереции. Судя по всему, это будет анонс beta-версии Android 12 с более детальным рассказом о том, что он нам принесёт, релизом новых библиотек и подходов.
Уверен, что будет детально рассказано про Jetpack Compose и его статус, возможно он уже будет production ready.
Тут можно решить небольшой ребус, а тут зарегистрироваться на само мероприятие, оно полностью бесплатное.
Ну и вы узнаете обо всех новинках конфереции первыми, так как подписаны на Android Live, так что следите за обновлениями. 😉
А может быть у вас есть идеи особых меропрятий для канала Android Live, которые посвящены этой конференции?
Можете поделиться в комментариях.
Сервисы для аналитики приложений
#library
Сервисы для анализа приложений — важные вещи для бизнеса: можно собрать информацию о пользователях, анализировать воронки, анализировать то, откуда пришли ваши пользователи и т.д.
Разработчики чаще используют Crashlytics, иногда добавляя сюда набор инструментов от Firebase. В целом, это хорошие инструменты, но ведь есть ещё ряд крутых сервисов, которые помогают анализировать приложения и их качество.
Ну а знания этих инструметов будет полезно в случае, если ваша роль в текущем проекте начинает выходить за рамки обычной разработки, или вы думаете о создании своего продукта. В любом случае, вы знаете, где взять их список, когда они понадобятся.
Весь список с детальным объяснением можно найти в этой статье, а мы рассмотрим несколько из описанных.
🔸продуктовая аналитика — нужна для получения информации о том, что конкретно делает пользователь в приложении. Сервисы — App Metrica и Firebase Analytics, Amplitude, Mixpanel.
🔸отправка пуш-уведомлений — полезны, если вы настраиваете группы пользователей, которым хотите их отправить. Сервисы — Firebase Cloud Messaging, AWS SNS, OneSignal.
🔸подключение платежей и подписок — очевидная и простая на первый взгляд вещь, но довольно непростая в реализации. Сервисы — Adapty, AppHud, RevenueCat.
🔸аналитика падений — наиболее близкая разработчикам вещь. Сервисы — AppMetrica, Firebase Crashlytics, Sentry.
Помните, что многие из описанных выше сервисов — платные, но многие из них дают бесплатную функциональность для маленьких продуктов.
#library
Сервисы для анализа приложений — важные вещи для бизнеса: можно собрать информацию о пользователях, анализировать воронки, анализировать то, откуда пришли ваши пользователи и т.д.
Разработчики чаще используют Crashlytics, иногда добавляя сюда набор инструментов от Firebase. В целом, это хорошие инструменты, но ведь есть ещё ряд крутых сервисов, которые помогают анализировать приложения и их качество.
Ну а знания этих инструметов будет полезно в случае, если ваша роль в текущем проекте начинает выходить за рамки обычной разработки, или вы думаете о создании своего продукта. В любом случае, вы знаете, где взять их список, когда они понадобятся.
Весь список с детальным объяснением можно найти в этой статье, а мы рассмотрим несколько из описанных.
🔸продуктовая аналитика — нужна для получения информации о том, что конкретно делает пользователь в приложении. Сервисы — App Metrica и Firebase Analytics, Amplitude, Mixpanel.
🔸отправка пуш-уведомлений — полезны, если вы настраиваете группы пользователей, которым хотите их отправить. Сервисы — Firebase Cloud Messaging, AWS SNS, OneSignal.
🔸подключение платежей и подписок — очевидная и простая на первый взгляд вещь, но довольно непростая в реализации. Сервисы — Adapty, AppHud, RevenueCat.
🔸аналитика падений — наиболее близкая разработчикам вещь. Сервисы — AppMetrica, Firebase Crashlytics, Sentry.
Помните, что многие из описанных выше сервисов — платные, но многие из них дают бесплатную функциональность для маленьких продуктов.
Dependency Injection vs Service Locator
#patterns
Многие разработчики не задумываются о разнице этих двух подходов. На первый взгляд, они одинаковы, решают одну и ту же проблему — увеличивают декомпозицию кода. Или простым языком — уменьшают связность разных участков кода, что даёт нам улучшенную тестируемость, масштабируемость и простоту.
Более того, разница между подходами может становиться ещё менее заметной, когда мы используем библиотеки. Но давайте остановимся более подробно на каждом из подходов, рассмотрим пример, чтобы увидеть разницу и понимать достоинства и недостатки каждого из них.
Хорошее определение этих паттернов нашёл в этой статье.
🟢 если описать DI одним словом, то идеально подходит слово «отдавать». И в самом деле, при помощи DI мы просто даём нужные объекты другому объекту. В примере ниже классу
DI именно о том, что зависимости предоставляются нам кем-то. И нашему классу не важно, где этот кто-то данные зависимости берёт. Поэтому, мы и используем для DI конструктор, а не setter.
🔵 если мы описываем Service Locator одним словом, то идеально подходит слово «взять». Так, и есть: у нас есть какой-то класс (локатор, фабрика) у которого мы берём объекты, которые нужны нашему классу. В примере ниже, мы возьмём объект класса
То есть локатор — это некая фабрика или контейнер, который наполняется готовыми объектами и из которого мы их получаем. Также нашему локатору не важно, как и кто положил эти объекты в него, его главная задача — предоставить объект, если он есть.
Современные библиотеки для внедрения зависимостей, такие как Dagger, Hilt, Koin, используют оба этих подхода в связке, хотя это и не всегда очевидно на первый взгляд. Но как мне кажется — это здорово, ведь каждый из них имеет свои плюсы, а подобное сосуществование уменьшает число недостатков.
#patterns
Многие разработчики не задумываются о разнице этих двух подходов. На первый взгляд, они одинаковы, решают одну и ту же проблему — увеличивают декомпозицию кода. Или простым языком — уменьшают связность разных участков кода, что даёт нам улучшенную тестируемость, масштабируемость и простоту.
Более того, разница между подходами может становиться ещё менее заметной, когда мы используем библиотеки. Но давайте остановимся более подробно на каждом из подходов, рассмотрим пример, чтобы увидеть разницу и понимать достоинства и недостатки каждого из них.
Хорошее определение этих паттернов нашёл в этой статье.
🟢 если описать DI одним словом, то идеально подходит слово «отдавать». И в самом деле, при помощи DI мы просто даём нужные объекты другому объекту. В примере ниже классу
House нужны объекты Door и Window, которые мы передаём ему в конструктор. val window = Window()
val door = Door()
val house = House(window, door)DI именно о том, что зависимости предоставляются нам кем-то. И нашему классу не важно, где этот кто-то данные зависимости берёт. Поэтому, мы и используем для DI конструктор, а не setter.
🔵 если мы описываем Service Locator одним словом, то идеально подходит слово «взять». Так, и есть: у нас есть какой-то класс (локатор, фабрика) у которого мы берём объекты, которые нужны нашему классу. В примере ниже, мы возьмём объект класса
House напрямую из какого-то локатора и будем использовать его дальше. val house = serviceLocator.get(House::class)То есть локатор — это некая фабрика или контейнер, который наполняется готовыми объектами и из которого мы их получаем. Также нашему локатору не важно, как и кто положил эти объекты в него, его главная задача — предоставить объект, если он есть.
Современные библиотеки для внедрения зависимостей, такие как Dagger, Hilt, Koin, используют оба этих подхода в связке, хотя это и не всегда очевидно на первый взгляд. Но как мне кажется — это здорово, ведь каждый из них имеет свои плюсы, а подобное сосуществование уменьшает число недостатков.
Kotlin Flows — шпаргалка
#flow
Многие на своих проектах уже давно используют
Вот вам ещё одна небольшая заметка про
Для тех, кто хочет шпаргалку сразу в pdf — вот ссылка, а сама статья с описание тут.
#flow
Многие на своих проектах уже давно используют
Flow в связке с Coroutines. На канале также было несколько постов о том, как лучше использовать эту связку и на что стоит обратить внимание. Вот вам ещё одна небольшая заметка про
Flow, где автор собрал в одну таблицу краткую информацию о них и о всех существующих типах Flow: в чём их разница, какие есть эквиваленты в RxJava, ссылки на документацию, примеры кода, где лучше применить их в Android. Для тех, кто хочет шпаргалку сразу в pdf — вот ссылка, а сама статья с описание тут.
Как правильно передавать данные между Fragments?
#jetpack #fragment
Для передачи данных между
• использовать интерфейсы и callbacks;
• использовать Shared
• использовать
Но есть ещё один способ, который сейчас является самым удобным и основным. Начиная с версии
Дальше мы должны добавить ключ, который хотели бы слушать, и будем принимать
Важно следить за уникальным использованием ключей, а также есть небольшие особенности при работе с
#jetpack #fragment
Для передачи данных между
Fragments есть несколько способов: • использовать интерфейсы и callbacks;
• использовать Shared
ViewModel;• использовать
setTargetFragment, правда он сейчас deprecated.Но есть ещё один способ, который сейчас является самым удобным и основным. Начиная с версии
Fragments 1.3.0-alpha04, FragmentManager имплементит FragmentResultOwner. Дальше мы должны добавить ключ, который хотели бы слушать, и будем принимать
Bundle с информацией. Для отправки результата надо использовать setFragmentResult с этим ключом, и добавить нужный нам Bundle.Важно следить за уникальным использованием ключей, а также есть небольшие особенности при работе с
childFragmentManager. Больше деталей и примеров кода можно найти тут.Планируем задачи с WorkManager
#workmanager #jetpack #beginners
У него есть несколько преимуществ в сравнении с предшественниками: например, работа при определённом заряде батареи или Интернета, гибкие настройки для повторного запуска, интеграция с
Если вы использовали только базовую часть
Ссылка на статью тут.
Были ли у вас проблемы с использованием WorkManager?
#workmanager #jetpack #beginners
WorkManager — довольно важный компонент из Jetpack, который позволяет планировать задачи вне зависимости от того было ли закрыто ваше приложение или перезагружено устройство. У него есть несколько преимуществ в сравнении с предшественниками: например, работа при определённом заряде батареи или Интернета, гибкие настройки для повторного запуска, интеграция с
Coroutines и RxJava.Если вы использовали только базовую часть
WorkManager или не использовали его совсем, то вот отличная статья с примерами, описывающая большинство кейсов использования: запуск периодичных задач, кастомные менеджеры для запуска, тестирование и debug. Ну и здесь же немного информации о том, как он работает под капотом для разных версий операционной системы. Ссылка на статью тут.
Были ли у вас проблемы с использованием WorkManager?
Лайфхаки для Firebase Remote Config
#firebase
Firebase Remote Config — это удобный сервис, который позволяет отправлять некий набор параметров через Firebase без участия вашего собственного сервера. Это удобно, ведь могут быть ситуации, когда у вас вообще нет сервера (например, в pet-проекте) или вам не просто добавить новую функциональность на ваш сервер.
Я активно использую инструменты Firebase, в том числе и этот. Нашёл статью, где автор описывает несколько хитростей для работы с Remote Config, возможно вы тоже найдёте для себя что-то полезное.
0️⃣Не забывайте о значениях по умолчанию в приложении. Об этом мало кто помнит, но вы можете установить значения по умолчанию для сервиса до тех пор, пока сервис не получить свой первый instance с Firebase. Это может быть полезно в случае каких-то проблем при получении данных. Сделать это можно двумя способами. Первый — это определение значений по умолчанию при получении определённой переменной, а второй — определить в самом config:
1️⃣Оберните получение данных в WorkManager. При использовании методов
2️⃣Свяжите Remote Config с Cloud Functions. Довольно спорное решение, но оно может быть полезно, если вы хотите доставить обновления Config как можно быстрее. Идея в том, что вы отправляете пуш-уведомление пользователям при изменении Remote Config, делая текущее состояние данных неактуальными и заставляя
#firebase
Firebase Remote Config — это удобный сервис, который позволяет отправлять некий набор параметров через Firebase без участия вашего собственного сервера. Это удобно, ведь могут быть ситуации, когда у вас вообще нет сервера (например, в pet-проекте) или вам не просто добавить новую функциональность на ваш сервер.
Я активно использую инструменты Firebase, в том числе и этот. Нашёл статью, где автор описывает несколько хитростей для работы с Remote Config, возможно вы тоже найдёте для себя что-то полезное.
0️⃣Не забывайте о значениях по умолчанию в приложении. Об этом мало кто помнит, но вы можете установить значения по умолчанию для сервиса до тех пор, пока сервис не получить свой первый instance с Firebase. Это может быть полезно в случае каких-то проблем при получении данных. Сделать это можно двумя способами. Первый — это определение значений по умолчанию при получении определённой переменной, а второй — определить в самом config:
Firebase.remoteConfig.apply {
setDefaultsAsync(mapOf(
"key" to "default_value"
))
}1️⃣Оберните получение данных в WorkManager. При использовании методов
fetch или fetchAndActivate, вы можете получить исключение, например когда пользователь не имеет подключения к Интернет. Правильнее всего попробовать получить эти данные ещё раз, когда будет восстановлено соединение. Можно испльзовать Worker, где в конфигурации настроить запуск только при наличии соединения: setRequiredNetworkType(NetworkType.CONNECTED).2️⃣Свяжите Remote Config с Cloud Functions. Довольно спорное решение, но оно может быть полезно, если вы хотите доставить обновления Config как можно быстрее. Идея в том, что вы отправляете пуш-уведомление пользователям при изменении Remote Config, делая текущее состояние данных неактуальными и заставляя
FirebaseRemoteConfig получить данные как можно быстрее при следующем запуске приложения.Автомиграции в Room
#room #jetpack
В версии Room 2.4.0-alpha01 добавили новую функциональность, которая значительно упрощает миграцию с одной версии базы данных на другую — автомиграции. До этой версии у вас было два пути при изменении схемы базы:
• писать миграцию вручную;
• заполнять базу данных заново, удаляя предыдущую версию базы.
Теперь появился гораздо более интересный способ. При повышении версии базы данных, вы можете указать параметр
Но не всё так просто: подобная функциольность будет работать только тогда, когда вы делаете какие-то простые изменения в структуре базы, такие как: добавление новой колонки, изменение primary key, foreign key или индексов, изменение значений по умолчанию в колонке. Для случаев посложнее, например разделение таблицы на несколько, всё равно придётся писать ручную миграцию.
Кроме этого, добавили
На мой взгляд — это отличная новость, которая избавит нас от написания большого числа лишнего кода в проекте. С нетерпением жду beta-версии.
#room #jetpack
В версии Room 2.4.0-alpha01 добавили новую функциональность, которая значительно упрощает миграцию с одной версии базы данных на другую — автомиграции. До этой версии у вас было два пути при изменении схемы базы:
• писать миграцию вручную;
• заполнять базу данных заново, удаляя предыдущую версию базы.
Теперь появился гораздо более интересный способ. При повышении версии базы данных, вы можете указать параметр
autoMigrations и добавить AutoMigration (from = 1, to = 2). Это всё, вы автоматически получите миграцию на новую версию. Более того, есть возможность комбинировать автомиграции и обычные миграции.Но не всё так просто: подобная функциольность будет работать только тогда, когда вы делаете какие-то простые изменения в структуре базы, такие как: добавление новой колонки, изменение primary key, foreign key или индексов, изменение значений по умолчанию в колонке. Для случаев посложнее, например разделение таблицы на несколько, всё равно придётся писать ручную миграцию.
Кроме этого, добавили
AutoMigrationSpec, которая может помочь Room сделать автомиграцию, если он не справляется сам. Там есть несколько аннотаций: DeleteTable, RenameTable, DeleteColumn, RenameColumn. В случае, если Room сам не сможет сделать миграцию, то вы получите exception. Это и будет являться признаком того, что надо использовать эти аннотации. На мой взгляд — это отличная новость, которая избавит нас от написания большого числа лишнего кода в проекте. С нетерпением жду beta-версии.