Коллега из сообщества (Максим Казанцев) опубликовал в публичный доступ 6 видео из своего курса по Kotlin Multiplatform.
🔸 О курсе и знакомство с автором
🔸 Инициализация проекта на KMP
🔸 Задачи в Gradle
🔸 Подключение Desktop + Compose
🔸 Добавление Android модуля
🔸 Подключение iOS таргета
Курс рассчитан на разработчиков от Junior+ и выше. Поэтому если вы не работали с KMP, или создавали проект с помощью визарда, но не совсем понимали как это сделать самостоятельно, то этот курс определенно для вас!
Приятного просмотра🤔
Курс рассчитан на разработчиков от Junior+ и выше. Поэтому если вы не работали с KMP, или создавали проект с помощью визарда, но не совсем понимали как это сделать самостоятельно, то этот курс определенно для вас!
Приятного просмотра
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥18🙏6👨💻4🤝3❤1
Давно на этом канале не было постов, но я пришел к вам с двумя хорошими новостями:
1️⃣ Я за это время сделал один интересный доклад про привычки Android разработки, которые мешают адаптировать приложение под KMP и скоро опубликуем его в открытый доступ, так что stay tuned
2️⃣ А также мы с командой подготовили новый 11 сезон Podlodka Android Crew с темой "Оптимизация UI".
Мы старались найти классных спикеров, помочь им с подготовкой и сезон получился довольно насыщенный:
🔹 Послушаем как продавать производительность бизнесу
🔹 Узнаем как работать с такими инструментами как Perfetto, JankStats и Jetpack Macrobenchmark
🔹 Увидим на примере как оптимизировать приложение на Jetpack Compose
🔹 А также поболеем за участников баттла и сами поучаствуем в квизе по производительности UI.
Конференция стартует уже 25 марта, так что присоединяйтесь, будет круто, все подробности на сайте.
🎁 Ну и куда же без розыгрыша? Давайте разыграем одну проходку на Android Crew, единственное условие – быть подписанными на этот telegram канал @kotlin_adept.
Для участия в розыгрыше достаточно нажать на кнопку «Принять участие» под следующим постом и мы определим победителя рандомно уже в это воскресенье, удачи🤝
Мы старались найти классных спикеров, помочь им с подготовкой и сезон получился довольно насыщенный:
Конференция стартует уже 25 марта, так что присоединяйтесь, будет круто, все подробности на сайте.
Для участия в розыгрыше достаточно нажать на кнопку «Принять участие» под следующим постом и мы определим победителя рандомно уже в это воскресенье, удачи
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7🔥2
Розыгрыш проходки на 11 сезон конференции Podlodka Android Crew
Kotlin Adept Notes
Розыгрыш проходки на 11 сезон конференции Podlodka Android Crew
Выбор дополнительных победителей (в количестве 1):
Победитель:
1. Mikhail (@zykloned)
Проверить результаты
Победитель:
1. Mikhail (@zykloned)
Проверить результаты
🔥2
Кастомные маски для TextField в Compose
Раньше в Android View реализовать маску для номера телефона, не говоря уже про что-то кастомное было далеко не самой простой задачей и люди, чтобы облегчить себе жизнь, использовали сторонние библиотеки, такие как Decoro.
Но теперь с приходом Compose надобность в сторонних решениях практически отпала, ведь реализовать кастомную маску для TextField можно буквально в 40 строк кода😱 , и это возможно благодаря продуманному и простому API интерфейса
Фишка в том, что
🔸 Определить как исходный текст будет трансформироваться в текст с маской
🔸 Предоставить двухсторонний маппинг для правильного смещения курсора в поле ввода
📘 Подробнее можно почтитать в статье, где разобран случай маски для ввода даты и с полностью кастомизируемой маской
#Compose
Раньше в Android View реализовать маску для номера телефона, не говоря уже про что-то кастомное было далеко не самой простой задачей и люди, чтобы облегчить себе жизнь, использовали сторонние библиотеки, такие как Decoro.
Но теперь с приходом Compose надобность в сторонних решениях практически отпала, ведь реализовать кастомную маску для TextField можно буквально в 40 строк кода
VisualTransformation
.Фишка в том, что
VisualTransformation
, как бы это неожиданно не звучало, влияет всего лишь на визуальное отображение, а не реальное значение поля, и, чтобы реализовать любую маску, достаточно сделать две вещи:
var out = ""
text.text.forEachIndexed { index, char ->
when (index) {
2 -> out += "/$char"
4 -> out += "/$char"
else -> out += char
}
}
val numberOffsetTranslator = object : OffsetMapping {
override fun originalToTransformed(offset: Int): Int {
if (offset <= 2) return offset
if (offset <= 4) return offset + 1
return offset + 2
}
override fun transformedToOriginal(offset: Int): Int {
if (offset <= 2) return offset
if (offset <= 5) return offset - 1
return offset - 2
}
}
#Compose
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8👍4❤1😁1
Forwarded from Android Broadcast
Media is too big
VIEW IN TELEGRAM
Немультиплатформенные привычки Android-разработки
Алексей Панов делится тем, как Android разработчику начать писать на Kotlin Multiplatform и отучиться от платформенных привычек
2:46 KMP Стек технологий
11:32 Переход с Java API
18:01 Переход с Android API
29:03 Использование Compose
36:07 Итоговые советы
Смотрите разбор на разных площадках:
👉YouTube
👉VK Video
👉Дзен
#AndroidBroadcast #кодинг
Алексей Панов делится тем, как Android разработчику начать писать на Kotlin Multiplatform и отучиться от платформенных привычек
2:46 KMP Стек технологий
11:32 Переход с Java API
18:01 Переход с Android API
29:03 Использование Compose
36:07 Итоговые советы
Смотрите разбор на разных площадках:
👉YouTube
👉VK Video
👉Дзен
#AndroidBroadcast #кодинг
❤10🔥9👍5⚡1
ViewModel в KMP
Еще не так давно считалось, что ViewModel — это только Android only история и использовать ее в общем коде в мультиплатформе не получится, но в мире KMP все меняется очень быстро:
😀 Google переписали ViewModel на Kotlin и адаптировали ее lifecycle под мультиплатформу
😀 JetBrains сделали ее полностью мультиплатформенной, заодно адаптировав и компоузовскую навигацию
Из нюансов, нужно явно создавать инстанс ViewModel, даже с пустым конструктором! Но при этом сохранилась поддержка savedStateHandle.
Эти изменения безусловно положительно повлияют на популяризацию KMP, такими темпами скоро достаточно будет просто перенести весь код Android приложения в папку commonMain, адаптировать gradle скрипты и можно запускать приложение на любой платформе. Звучит круто, не правда ли!👌
Но все же я не рекомендую продолжать использовать ViewModel напрямую, а думать о ней как о контейнере! Например, так реализован InstanceKeeper в Essenty.
Это дает несколько плюсов:
😀 Вы можете сами управлять ЖЦ вашего компонента с логикой, делать его как синглтон, инжектить друг в друга, а не привязывать его только к ЖЦ ViewModel
😀 Вы облегчаете внедрение зависимостей, так как по сути вы создаете обычный класс
Если все равно непонятно о чем речь, то советую прочитать эту статью, где подробно рассмотрена эта концепция.
А что вы думаете об использовании ViewModel в KMP❓
Еще не так давно считалось, что ViewModel — это только Android only история и использовать ее в общем коде в мультиплатформе не получится, но в мире KMP все меняется очень быстро:
Из нюансов, нужно явно создавать инстанс ViewModel, даже с пустым конструктором! Но при этом сохранилась поддержка savedStateHandle.
@Composable
fun MyScreen(viewModel: MyViewModel = viewModel { MyViewModel(createSavedStateHandle()) }) {
...
}
Эти изменения безусловно положительно повлияют на популяризацию KMP, такими темпами скоро достаточно будет просто перенести весь код Android приложения в папку commonMain, адаптировать gradle скрипты и можно запускать приложение на любой платформе. Звучит круто, не правда ли!
Но все же я не рекомендую продолжать использовать ViewModel напрямую, а думать о ней как о контейнере! Например, так реализован InstanceKeeper в Essenty.
Это дает несколько плюсов:
Если все равно непонятно о чем речь, то советую прочитать эту статью, где подробно рассмотрена эта концепция.
А что вы думаете об использовании ViewModel в KMP
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥16
Сегодня буду выступать на митапе от Usetech. Буду рассказывать обновленную версию своего доклада, ведь с тех пор картина сильно поменялась, теперь Room, ViewModel, Jetpack Navigation Compose уже можно использовать в KMP. Так что грань между Android и мультиплатформенной разработкой все больше стирается.
Поэтому если не смотрели доклад или хотите узнать, что поменялось и задать вопросы, то приходите сегодня в 15:00 мск на прямую трансляцию.
Также, помимо меня, на митапе выступят Анна Жаркова с докладом про SwiftUI и Евгений Сатуров с докладом про Flutter.
Регистрируйтесь по ссылке и до встречи🤝
Поэтому если не смотрели доклад или хотите узнать, что поменялось и задать вопросы, то приходите сегодня в 15:00 мск на прямую трансляцию.
Также, помимо меня, на митапе выступят Анна Жаркова с докладом про SwiftUI и Евгений Сатуров с докладом про Flutter.
Регистрируйтесь по ссылке и до встречи
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥15❤🔥1
В докладе много всего интересного про подкапотную магию работы Compose, а именно:
Приятного просмотра
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥30❤3🎉3🦄3
Также Mobius опубликовали наш совместный с Дмитрием Григорьевым квиз по Compose🎨
Квиз состоит из 4 блоков:
🟡 Разминочные вопросы
🔵 Вопросы по модификаторам
🟠 Вопросы по рекомпозиции
🔵 Хардкорные вопросы про подкапотную магию Compose
Так что, если не смотрели, то проверьте свои знания по Compose и напишите в комментариях на сколько вопросов удалось ответить правильно и какой вопрос показался самым сложным🤔
Квиз состоит из 4 блоков:
Так что, если не смотрели, то проверьте свои знания по Compose и напишите в комментариях на сколько вопросов удалось ответить правильно и какой вопрос показался самым сложным
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7🔥3👍1
This media is not supported in your browser
VIEW IN TELEGRAM
Коллега из Контура, Евгений Мельцайкин, написал статью о том, как сделать такую кнопку с помощью кастомного Layout в Compose и как оптимизировать ее, чтобы достичь минимального количества рекомпозиций. Приятного чтения 📕
Исходный код можно посмотреть здесь🐱
А вы сможете на взгляд определить какая кнопка сделана оптимально по количеству рекомпозиций?
#Compose
Исходный код можно посмотреть здесь
А вы сможете на взгляд определить какая кнопка сделана оптимально по количеству рекомпозиций?
#Compose
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥37👍2
Обзор Mobius 2024 Spring
Прошла очередная конференция Mobius и в этот раз я даже посмотрел больше двух докладов, так как фармить мерч удаленно не получается😒
И в целом сезон получился довольно интересным с хорошими и полезными докладами.
Вот мой личный топ:
🔸 Тестирование дизайн-системы. Тут автор рассказывает про то, как они работают со snapshot тестами, с какими проблемами столкнулись, какие уроки из этого вынесли и как у них получилось избавиться от эмулятора при прогоне тестов.
Для нас сейчас это довольно актуальная тема, у нас уже был первый подход к скриншот тестированию, но мы также наткнулись на проблемы и нам ещё предстоит их преодолеть.
🔸 Единая авторизация Ozon ID. Довольно лёгкий и менее технический доклад про способы авторизации, про часть из которых я узнал из доклада и выглядят они действительно интересно.
🔵 Бессмертное приложение. Скорее не доклад, а больше справочник по разным лайфхакам как продлить время жизни приложения в фоне и пережить force stop, которые вы вряд ли найдете на StackOverflow.
🔹 Как избавиться от рекурсии. Хардкорный, но интересный доклад про различные способы оптимизации рекурсии.
Так что, советую посмотреть эти доклады в записи, но если у вас нет билета на Mobius, то пишите в комментарии какую тему хотелось бы осветить и я напишу пост про самые важные инсайты из докладов💻
Прошла очередная конференция Mobius и в этот раз я даже посмотрел больше двух докладов, так как фармить мерч удаленно не получается
И в целом сезон получился довольно интересным с хорошими и полезными докладами.
Вот мой личный топ:
Для нас сейчас это довольно актуальная тема, у нас уже был первый подход к скриншот тестированию, но мы также наткнулись на проблемы и нам ещё предстоит их преодолеть.
Так что, советую посмотреть эти доклады в записи, но если у вас нет билета на Mobius, то пишите в комментарии какую тему хотелось бы осветить и я напишу пост про самые важные инсайты из докладов
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10👏8👍3🤩2
Скриншот-тестирование
Практика скриншот-тестирования в Android началась еще более 10 лет назад и актуальна по сей день, за это время появилось огромное количество разных библиотек (Paparazzi, Shot, Testify и другие), но у всех библиотек есть существенный недостаток — поддержка. Всегда есть риски, что библиотеку перестанут поддерживать или будут обновлять зависимости несвоевременно.
И ребята из Тинькофф для тестирования дизайн-системы пошли другим путем, не используя сторонние библиотеки, так как все, что нужно для скриншот-тестирования уже есть в Android! (на самом деле нет)
Достаточно взять эталонный и текущий скриншот, сконвертировать все в Bitmap и попарно сравнить пиксели:
Но разумеется это только верхушка айсберга и, чтобы построить хороший процесс тестирования дизайн-системы, нужно решить еще множество проблем.
И вот список рекомендаций из их доклада про что нужно помнить:
▫️ Подготовьте storybook и используете эти же состояния компонентов для тестирования
▫️ Сделайте удобный тулинг для обновления эталонных скриншотов и просмотра диффа скриншотов
▫️ Используйте CI как единый источник правды для создания эталонных скриншотов, так как на разных процессорах графика может отличаться
▫️ Избавляйтесь от запуска тестов на эмуляторе, в этом может Robolectric с режимом
▫️ Подумайте о генерации тестов через KSP
Но, что если ваш проект полностью написан на Jetpack Compose? Неужели нет других вариантов скриншот-тестирования? Об этом расскажу в следующем посте, так что stay tuned!
#Testing #SnapshotTesting #Android
Практика скриншот-тестирования в Android началась еще более 10 лет назад и актуальна по сей день, за это время появилось огромное количество разных библиотек (Paparazzi, Shot, Testify и другие), но у всех библиотек есть существенный недостаток — поддержка. Всегда есть риски, что библиотеку перестанут поддерживать или будут обновлять зависимости несвоевременно.
И ребята из Тинькофф для тестирования дизайн-системы пошли другим путем, не используя сторонние библиотеки, так как все, что нужно для скриншот-тестирования уже есть в Android! (на самом деле нет)
Достаточно взять эталонный и текущий скриншот, сконвертировать все в Bitmap и попарно сравнить пиксели:
val referenceBitmap = BitmapFactory.decodeFile("assets/1.jpg")
val actualBitmap = onView(withId(R.id.mainContent)).captureToBitmap()
val isSameImage = compareBitmaps(referenceBitmap, actualBitmap)
assertTrue(isSameImage)
Но разумеется это только верхушка айсберга и, чтобы построить хороший процесс тестирования дизайн-системы, нужно решить еще множество проблем.
И вот список рекомендаций из их доклада про что нужно помнить:
@GraphicsMode(NATIVE)
Но, что если ваш проект полностью написан на Jetpack Compose? Неужели нет других вариантов скриншот-тестирования? Об этом расскажу в следующем посте, так что stay tuned!
#Testing #SnapshotTesting #Android
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥15👍2❤1
Скриншот-тестирование в Compose
Google не так давно выкатили свой тулинг для скриншот-тестирования в Compose в экспериментальном режиме и работает он на основе Compose Preview👀
У меня довольно скпептическое отношение к превью, за все время работы с Compose у меня постоянно были какие-то проблемы с этим механизмом, а с приходом Compose Multiplatform заставить превьюшки работать тот ещё челлендж, более менее дела с превью обстоят только в новой IDE Fleet, но там ещё ворох других проблем.
Так вот, вернёмся к тестированию, я попробовал этот способ и что могу сказать по текущему состоянию тулинга:
👍 Официальное решение для скриншот-тестирования
👍 Генерация отчёта с диффом изображений
👍 Уже относительно работает и можно использовать на свой страх и риск
👍 Тесты прогоняются без эмулятора и соответственно прогоняются быстро
👎 Названия сгенерированных скриншотов нельзя поменять
👎 Нельзя выборочно обновить эталонный скриншот
👎 Нужно использовать специальные gradle таски для валидации скриншотов, потребуются доработки на CI
👎 Нельзя настроить минимальный порог отличий между скриншотами
👎 Только для Android
Так что подводя итоги, круто, что появляется решение из коробки, но в текущем состоянии завязываться на него довольно опасно.
#Compose #SnapshotTesting
Google не так давно выкатили свой тулинг для скриншот-тестирования в Compose в экспериментальном режиме и работает он на основе Compose Preview
У меня довольно скпептическое отношение к превью, за все время работы с Compose у меня постоянно были какие-то проблемы с этим механизмом, а с приходом Compose Multiplatform заставить превьюшки работать тот ещё челлендж, более менее дела с превью обстоят только в новой IDE Fleet, но там ещё ворох других проблем.
Так вот, вернёмся к тестированию, я попробовал этот способ и что могу сказать по текущему состоянию тулинга:
Так что подводя итоги, круто, что появляется решение из коробки, но в текущем состоянии завязываться на него довольно опасно.
#Compose #SnapshotTesting
Please open Telegram to view this post
VIEW IN TELEGRAM
❤11👍8
Бессмертное приложение
Продолжим разбирать доклады с предыдущего Mobius. И сегодня поговорим о том, как пережить force stop и запустить приложение после его установки из стора без действий пользователя.
Мы знаем, что если пользователь принудительно остановит в настройках приложение, то без повторного его открытия все фоновые операции будут недоступны, в том числе и пуши. Но эту проблему можно частично решить, для этого нам понадобится
1. Регистрируем в манифесте provider с метадатой ContactDirectory. Тогда при открытии приложения "Контакты" ContactsProvider опросит всех, у кого есть эта метадата, соответственно поднимется наш провайдер и вызовется метод
2. Далее мы можем зарегистрировать свой
Но согласитесь, это же не бессмертие, а больше похоже на некромантию? Убиваем и воскрешаем процесс через какое-то время💀
Однако есть способ по-настоящему пережить force stop, правда работает он не гарантировано и ни в каких продакшн приложениях лучше его не использовать⚠️
Суть в том, что у системы есть 40 попыток, чтобы убить процесс с периодичностью 5мс, и если мы будем за это время создавать новые процессы, то система в теории просто сдастся. То есть процессы будут поднимать друг друга пока не пройдет достаточно времени, чтобы система оставила их в покое. Посмотреть на это безумие можно в репозитории.
Всем разработчикам долгоживущих приложений, а пользователям соболезнования по поводу батарейки в их смартфонах🫡
#Android #UnderTheHood
Продолжим разбирать доклады с предыдущего Mobius. И сегодня поговорим о том, как пережить force stop и запустить приложение после его установки из стора без действий пользователя.
Мы знаем, что если пользователь принудительно остановит в настройках приложение, то без повторного его открытия все фоновые операции будут недоступны, в том числе и пуши. Но эту проблему можно частично решить, для этого нам понадобится
ContactsProvider
и Account Synchronization
.1. Регистрируем в манифесте provider с метадатой ContactDirectory. Тогда при открытии приложения "Контакты" ContactsProvider опросит всех, у кого есть эта метадата, соответственно поднимется наш провайдер и вызовется метод
onCreate
у Application
даже без первичного запуска приложения.
<meta-data
android:name="android.content.ContactDirectory"
android:value="true" />
2. Далее мы можем зарегистрировать свой
SyncAdaper
для синхронизации аккаунтов, он может не иметь никакой логики, главное включить автоматический и периодичный синк. Тогда система сможет при синхронизации аккаунтов сама пробудить процесс даже после force stop!Но согласитесь, это же не бессмертие, а больше похоже на некромантию? Убиваем и воскрешаем процесс через какое-то время
Однако есть способ по-настоящему пережить force stop, правда работает он не гарантировано и ни в каких продакшн приложениях лучше его не использовать
Суть в том, что у системы есть 40 попыток, чтобы убить процесс с периодичностью 5мс, и если мы будем за это время создавать новые процессы, то система в теории просто сдастся. То есть процессы будут поднимать друг друга пока не пройдет достаточно времени, чтобы система оставила их в покое. Посмотреть на это безумие можно в репозитории.
Всем разработчикам долгоживущих приложений, а пользователям соболезнования по поводу батарейки в их смартфонах
#Android #UnderTheHood
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥17😱13😁2🤡1🌚1👨💻1
Корутинные рецепты
Возможно вы уже видели набор полезных рецептов для Kotlin Coroutines от Marcin Moskala. Это набор утилитарных функций, которые помогают в повседневной разработке, позволяют значительно сократить код и сделать его лаконичнее.
🔹 Функция mapAsync позволяет элегантно сделать загрузку данных параллельной при работе с коллекциями
🔹 Функции retryWhen и retryBackoff позволяют сделать повторные запросы в случае ошибки, а вторая функция позволяет сделать ожидание экспоненциальным, чтобы увеличить вероятность успешного повтора
🔹 Функция raceOf позволяет запустить несколько suspend функций параллельно и получить результат той, что завершится быстрее остальных. На моей практике, это единственная функция, которая использует механизм select в корутинах.
🔹 Функция suspendLazy позволяет создать ленивое suspending свойство, которое не будет блочить поток, обращающийся к этому свойству
🔹 Ну и различные SharedDataSource и StateDataSource, которые нужны, чтобы пошарить один экземпляр Flow для нескольких подписчиков по переданному ключу.
📎 Помимо этих рецептов, также есть либа с полезными операторами для Flow, взятыми из Rx.
💡 Еще к этому списку можно было бы докинуть runCatchingCancellable, который не съедает CancellationException или функцию, противоположную raceOf, которая выберет самый медленный источник, ведь иногда нам нужно, наоборот, подзамедлить UI, чтобы он не мелькал и пользователь понимал, что происходит на экране.
Если вы знаете еще полезные экстеншены для корутин, делитесь ими в комментариях💬
#Coroutines
Возможно вы уже видели набор полезных рецептов для Kotlin Coroutines от Marcin Moskala. Это набор утилитарных функций, которые помогают в повседневной разработке, позволяют значительно сократить код и сделать его лаконичнее.
Если вы знаете еще полезные экстеншены для корутин, делитесь ими в комментариях
#Coroutines
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥29
👉 Какая IDE лучше?
👉 Чьи приложения качественней?
👉 У кого лучше дизайн?
👉 Где больше инноваций?
👉 Зачем натив, если есть кроссплатформа?
В шоу ведущий сталкивает двух представителей из разных сфер в IT и накидывает спорные тезисы, а затем участники обсуждают согласны ли они с этими утверждениями или нет.
Если вам по душе подобный формат, то тут оставил плейлист со всеми выпусками.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤12👍7🔥4🫡1
Custom Quick Settings tiles
Забавно, что являясь Android разработчиком, мне очень редко приходится решать задачи, связанные с самой платформой и ее фичами, и, думаю, я такой не один. Но недавно появилась потребность добавить свою кастомную плитку для приложения в шторку с быстрыми настройками.
Каждая такая плитка представляет из себя специальный сервис под названием
Проблема только в том, что нашел я этот гайд уже после того как сам разобрался, что к чему, ведь по запросу😒
Главное, что нужно знать, что обновлять плитку можно только в промежутке между🤔 . Как по мне, первый способ является более удобным, но разумеется все зависит от конкретного кейса.
⚠️Однако я столкнулся с одной проблемой, само по себе взаимодействие с
💬 А используете ли вы данную функциональность в своих приложениях? Если да, то какие сценарии вы туда выносите?
#Android
@kotlin_adept
Забавно, что являясь Android разработчиком, мне очень редко приходится решать задачи, связанные с самой платформой и ее фичами, и, думаю, я такой не один. Но недавно появилась потребность добавить свою кастомную плитку для приложения в шторку с быстрыми настройками.
Каждая такая плитка представляет из себя специальный сервис под названием
TileService
. Это особый вид bound сервиса, который имеет свои особенности жизненного цикла и все нюансы подробно описаны в гайде. Проблема только в том, что нашел я этот гайд уже после того как сам разобрался, что к чему, ведь по запросу
TileService
отдавало все что угодно: скудную документацию, статьи подозрительного качества, но только не гайд Главное, что нужно знать, что обновлять плитку можно только в промежутке между
onStartListening()
и onStopListening()
и по умолчанию этот промежуток соответствует поведению, когда плитка видна на экране у пользователя, что выглядит довольно логично и похоже на то, как мы подписываемся на стейт в UI, но Google почему-то рекомендует явно запрашивать listening state ⚠️Однако я столкнулся с одной проблемой, само по себе взаимодействие с
TileService
не переводит ваше приложение в состояние foreground и вы можете столкнуться с различными ограничениями системы. В моем случае помог запуск отдельного foreground сервиса из TileService.#Android
@kotlin_adept
Please open Telegram to view this post
VIEW IN TELEGRAM
👍31👨💻3❤1
Нашли серьезную уязвимость в Jetpack Navigation Compose, которая позволяет открыть любой экран в приложении, даже если там нет явных диплинков ⚠️
Эксплуатируется она максимально просто, достаточно знать имя пакета и название маршрута в графе навигации:
Как защититься
1. Разумеется лучший вариант не использовать данную навигацию, можете посмотреть мой пост со сравнением библиотек навигации для Compose и выбрать подходящую
2. Если в приложении не используются диплинки, можно частично решить проблему перетерев data в определенном intent:
#Security #Compose
@kotlin_adept
Эксплуатируется она максимально просто, достаточно знать имя пакета и название маршрута в графе навигации:
Intent().apply {
setClassName("your.package", "your.package.MainActivity")
data = Uri.parse("android-app://androidx.navigation/YOUR_DESTINATION")
startActivity(this)
}
Как защититься
1. Разумеется лучший вариант не использовать данную навигацию, можете посмотреть мой пост со сравнением библиотек навигации для Compose и выбрать подходящую
2. Если в приложении не используются диплинки, можно частично решить проблему перетерев data в определенном intent:
val intentData = intent.dataString
if (intentData != null && intentData.startsWith("android-app://androidx.navigation")) {
intent.setData(null)
}
#Security #Compose
@kotlin_adept
Please open Telegram to view this post
VIEW IN TELEGRAM
😁13👍6🔥5😱4👀2👻1