Kotlin Adept Notes
2K subscribers
69 photos
11 videos
116 links
Канал о разработке на Kotlin и обо всем, что с ним связано
По всем вопросам и рекламе: @ajiekcx
Download Telegram
Генерация сетевых моделей

Сейчас AI используют везде, где только можно и довольно часто можно встретить в опросах, что AI применяют для преобразования JSON в сетевые модели для взаимодействия с API бэкенда. Однако эту задачу довольно легко решает OpenAPI Generator, при условии, что бэкендеры сделали нормальную документацию, конечно 😁

Использование автогенерации моделей по спеке OpenAPI даёт сразу несколько преимуществ:
🟢 Вы не тратите время на написание бойлерплейт кода
🟢 Исключаете человеческий фактор, например, можно случайно забыть сделать поле nullable или наоборот
🟢 Всегда поддерживаете API-сущности в актуальном состоянии, так как спецификация OpenAPI напрямую связана с кодом бэкенда (ну, почти 🙃)

При этом благодаря Mustache шаблонам можно реализовать очень гибкое решение:
🟡 Использовать любую библиотеку для сериализации
🟡 Сразу маппить данные в нужные типы, например, в Instant из kotlinx-datetime
🟡 Поддерживать полиморфную сериализацию, когда ответы от API могут сильно различаться
🟡 И даже генерировать не только модели, но и код для взаимодействия с HTTP-клиентом, например, с Ktor

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

💭 А как вы создаете API-сущности в своих проектах?

#Network #OpenAPI
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥421
Советы по сканированию DataMatrix

Если вам интересно, чем закончился мой вайбкодинг по созданию сканера для распознавания всех видов DataMatrix (DM), то вот к чему я пришёл:

🟡 Google ML Kit оказался производительнее ZXing по нашим замерам. Осталась проблема с тем, что ML Kit не распознаёт белые DM на чёрном фоне.
🟡 Самое простое решение оказалось самым эффективным: для сканирования инвертированных DataMatrix нужно инвертировать Bitmap. Однако всё не так просто.
🟡 Самый эффективный способ инвертировать Bitmap — использовать ColorMatrix и нарисовать Bitmap на Canvas. Пример оставлю в комментариях.
🟡 Другая проблема заключалась в том, что CameraX отдаёт изображение в формате YUV, и стандартный метод конвертации ImageProxy в Bitmap может упасть с ошибкой UnsupportedOperationException. Тут два пути решения: написать свой конвертер или выставить в настройках камеры OutputImageFormat в формат RGBA.
🟡 А чтобы одновременно работать с обычными и инвертированными DM, лучше не использовать один ImageProxy, а сделать разные анализаторы и раскидывать кадры между ними по очереди, объединив их с помощью паттерна «Компоновщик».

#CameraX #GoogleMLKit
Please open Telegram to view this post
VIEW IN TELEGRAM
👍25🤔31
Как самому зашифровать SharedPreferences

Вы наверняка знаете, что решение от Google в виде EncryptedSharedPreferences уже давно Deprecated, а какой-то адекватной замены им так и не появилось. И что делать, если безопасники отказываются принимать оговорку, что префы может читать только само приложение, если на устройстве нет рута? ☹️

Остается только написать свое решение и, на самом деле, сделать это не сильно сложно. Для этого нам понадобится AndroidKeystore и Tink — open-source решение от Google для работы с криптографией, которое очень удобно в использовании.

Алгоритм получается следующий:
1. В AndroidKeystore создаем новый ключ, если его еще нет
2. В Tink генерируем KeysetHandle
3. На основе этих данных создаем encryptedKeyset средствами Tink и сохраняем его в SharedPreferences
4. Затем из keysetHandle достаем примитив AEAD, с помощью которого уже будем шифровать данные
5. PROFIT

В этой реализации главное учесть два момента:
🔘Обязательно удалять ключ из AndroidKeystore при очистке префов
🔘Разработать стратегию на случай, если encryptedKeyset в префах или ключа в Keystore не оказалось, иначе вы не сможете расшифровать ваши данные!

Ну а дальше уже дело техники, если тема интересна, то я постараюсь собрать сниппет с кодом 😉
Please open Telegram to view this post
VIEW IN TELEGRAM
👍66🔥51😁1👌1
Зашифрованные префы для MultiplatformSettings

Как и обещал, выкладываю в общий доступ реализацию шифрования SharedPreferences с помощью библиотеки Tink и AndroidKeystore.

В данном случае реализация сделана для библиотеки MultiplatformSettings, но вы легко можете адаптировать ее для обычных SharedPreferences.

⚠️ Специально выкладываю решение как gist, потому что никаких гарантий нет, используйте на свой страх и риск!

🌐 Исходный код здесь

P.S. За реализацию скажем спасибо Евгению Мельцайкину 😎
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥24
Просмотр Markdown файлов в Android Studio

Если вы, как и я, не знали, что в студии можно просматривать форматированные .md-файлы, то держите рецепт, как починить отображение:

1. Откройте Help → Find Action
2. Введите "Choose Boot Java Runtime for the IDE"
3. В выпадающем списке в поле New выберите runtime с поддержкой JCEF.
4. Перезагрузите IDE

Это особенно полезно при работе с AI агентом Junie, который генерит ответы в этом формате.

#Markdown #AndroidStudio
354👍2
🛶 Новый сезон Podlodka Android Crew стартует уже через два месяца, а значит, пора выбрать тему сезона и нам нужна ваша помощь выбрать лучшую.

Мы подготовили три потенциальных темы:

🛠 Тулинг: от AI до Я
- Расскажем как грамотно использовать AI-агенты
- Узнаем тайную магию дебаггера
- Поделимся must-have плагинами

🔋 Работа в фоне
- Узнаем как сделать музыкальный плеер
- Разберемся как работать в фоне в KMP
- Поговорим про новые фичи, вроде Live Updates

⚙️ Архитектура: AI, KMP, SDK
- Научимся проектировать SDK
- Посмотрим дебаты про BDUI
- Узнаем, чем занимается мобильный архитектор

📊 Пройдите, пожалуйста, опрос по ссылке.

А среди тех, кто пройдет опрос до 20 июля включительно, мы разыграем проходку на грядущий сезон 🎁
Please open Telegram to view this post
VIEW IN TELEGRAM
🤝15🔥3🫡1
Make Snackbar Great Again

В Compose реализация показа snackbar получилась не самой удобной, на каждом экране приходится:
🔘 Оборачивать контент в Scaffold
🔘 Вызывать suspend-функции для показа snackbar
🔘 Не забывать предусмотреть отмену предыдущего snackbar
🔘 Страдать из-за BottomSheet, так как там не получится использовать Scaffold, иначе он растянется на весь экран

И даже если сделать один глобальный обработчик, snackbar будет залезать на BottomNavigation, что выглядит довольно плохо 🤔

Вот что я предлагаю:
🟢Отказаться от показа snackbar через Scaffold и написать простую логику с декларативным отображением snackbar с анимацией в зависимости от состояния.
🟢Чтобы snackbar не перекрывал лишние элементы интерфейса, можно написать кастомный модификатор в Compose, который будет запоминать верхнюю позицию элемента, к которому он применён, и добавлять неявный отступ к snackbar.

Таким образом, эта реализация не только решает проблемы выше, но и позволяет отображать snackbar как внизу, так и вверху экрана.

🔥 Если тема интересна, ставьте реакции и я попробую собрать пример с такой реализацией.

#Compose
Please open Telegram to view this post
VIEW IN TELEGRAM
1🔥121🥴9👍84
📂 Папка с Android-блогерами

Мы решили заколлабиться с крутыми инженерами, которые ведут блоги об Android-разработке и делятся авторским контентом.

Добавляйте папку себе, если вам интересно послушать разные мнения и советы на повседневные темы разработки 😉
Please open Telegram to view this post
VIEW IN TELEGRAM
19😴3
📣 По вашим заявкам сделал небольшую библиотеку для декларативного показа снекбаров.

Преимущества библиотеки:
🟢 Полностью декларативный API, забудьте про one-time события и их обработку в LaunchedEffect.
🟢 Можно сделать как один глобальный обработчик, так и множество вложенных.
🟢 Благодаря встроенным модификаторам важный UI не будет перекрываться снекбаром.
🟢 Можно отображать снекбар как внизу, так и вверху экрана.
🟢 Поддерживаются любые типы сообщений, а не только строки.
🟢 Нет зависимости от Material, отображайте любой UI, какой захотите.
🟢 Настраиваемые анимации появления и скрытия снекбара.
🟢 Поддерживаются Android, iOS и JVM-таргеты.
🟢 Простая интеграция с Decompose.

🌐 Инструкцию по подключению, сэмпл и исходный код смотрите в репозитории.

Звёздочки на репозиторий и репосты приветствуются!

#Compose #Snackbar #KMP
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥69👍94🤔1
Как слить кодовую базу из-за Compose Multiplatform

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

Если в Android мы переживаем за то, чтобы никто не зареверсил наш код, подключаем R8 и так далее, то как обеспечить такой же уровень защиты в вебе?

Казалось бы, там всё ок из коробки: в релизном билде что-то понять из итогового JS-файла не получится, особенно с Wasm.

Но есть один маленький нюанс: по умолчанию в настройках Webpack исходный код тоже публикуется, и его любой может успешно посмотреть в Developer Tools. А в документации по Compose Multiplatform нет ни одного упоминания о том, как это предотвратить 🤡

Так что обязательно отключайте публикацию сорсов в настройках Webpack на релизе. Как это сделать — смотрите в комментариях 👇

#Security #Compose #WEB
Please open Telegram to view this post
VIEW IN TELEGRAM
28👍18🤬4🔥2
Как AI помогает в мобильной разработке

Да, AI добрался и до этого канала... Знаю, что многих уже тошнит от упоминания этих букв в инфополе, но таков путь. При этом, по моим наблюдениям, далеко не все разработчики поработали с AI-агентами, а зря, ведь многие задачи уже можно не делать самому:

Что уже можно отдать AI
🟢 Любую задачу, которую вы понимаете, как решить, и можете это сформулировать в тексте
🟢 Генерацию вёрстки по макетам в Figma
🟢 Написание документации
🟢 Код-ревью
🟢 Анализ крашей и ошибок
🟢 Объяснение сложных участков в коде и так далее

Что пока не стоит
🔘 Задачи, в которых нужно проявить креативность и нет понятного решения
🔘 Работу с экзотическими технологиями, вроде интеропа с Objective-C в Kotlin Native
🔘 Обновление зависимостей в проекте
🔘 Создание архитектуры приложения

Напоследок порекомендую доклады (раз, два) от наших коллег из сообщества, которые делятся своим опытом применения AI.

#AI #Mobile
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍40👎16🥱8🥴5🤡1
This media is not supported in your browser
VIEW IN TELEGRAM
23 августа пройдет Yandex Mobile Runtime — фест для мобильных разработчиков

Забудьте про скучные лекции с десятками слайдами. Будем прокачиваться здесь и сейчас. Участников ждет AI-хакатон, карьерные консультации с экспертами Яндекса, воркшопы по MCP и ускорению приложений, и не только.

А еще — можно поучаствовать в дискуссии от Городских сервисов по метрикам, тестированию и BDUI, поиграть в настолки в зоне от экспертов Поиска и рекламных технологий и заглянуть в кастомный бар с коктейлями от команды Яндекс 360.

Не пропустите — регистрация уже открыта.
👍7🎃1
Тестирование мобильных приложений

Давайте поговорим о том, как можно организовать процесс тестирования мобильных приложений. За свою практику я познакомился с разными подходами и вот какие плюсы и минусы я вижу:

1. Ручное тестирование
Самый распространённый вариант, когда в команде есть QA, и он тестирует новые фичи и проводит регрессию.
Лучший способ находить самые непредсказуемые баги, о которых разработчик даже не мог подумать.
Дорого: нужно содержать штат QA, покупать девайсы для тестирования. А если регресс занимает пару дней, получаем ещё и выгоревших сотрудников.

2. Автотесты на эмуляторах/симуляторах
Второй по популярности вариант, автоматизируем те же тест-кейсы, что и проходит тестировщик. Так мы можем быть почти уверены, что ничего не сломали.

Позволяет автоматизировать регресс, UI-тесты проходят значительно быстрее ручного тестирования.
Есть множество проблем с поддержкой UI-тестов, и далеко не всё можно проверить на эмуляторе/симуляторе.

3. Мобильная ферма
В этом случае мы используем ферму из реальных устройств, на ней можно проводить как ручное тестирование, так и запускать UI-тесты.

Такой подход используют, например, в Яндексе с более чем 800 устройствами. Я не представляю, сколько это стоит, ведь для каждого iPhone нужен отдельный MacBook ☠️
Из open source-решений есть STF и DeviceHub, у которых тоже есть свои плюсы и минусы.
Другой вариант — аренда фермы девайсов. Например, такие услуги предоставляет компания Selectel.

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

🔖 Если тема заинтересовала и хотите узнать подробнее, то есть хорошая статья по теме, рекомендую!

#Testing #MobileFarm
Please open Telegram to view this post
VIEW IN TELEGRAM
👨‍💻17
Вы знаете, я люблю острые ощущения, поэтому решил попробовать встроить Jetpack Compose экран в приложение на React Native.

Так вот, это была ошибка, я по дороге несколько раз умер 😵

Казалось бы, читаем документацию, как встроить AndroidView в RN, оборачиваем ComposeView во FrameLayout и готово, делов-то.

И всё хорошо, пока эта вьюшка отображается на первом экране, но из-за особенностей навигации в RN будем получать ошибку cannot locate windowRecomposer.

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

Исходников, конечно, я не нашёл, поэтому скормил скриншоты из доклада ChatGPT, чтобы она восстановила код, и это даже заработало 🤯

🌐 Выкладываю gist для таких же искателей приключений, но полноценно я это ещё не протестировал, так что используйте аккуратно.

P.S. Слабонервным код лучше не смотреть
Please open Telegram to view this post
VIEW IN TELEGRAM
😁34🤡3🙏2
Разумеется, вы слышали о нашумевшем обновлении iOS с Liquid Glass: на картинках всё выглядит красиво, но как это будет выглядеть в вашем приложении, если все нативные компоненты разом поменяются? И как успеть всё исправить до релиза?

Мой коллега, Антон Долганов, написал классную статью о том, как мы готовимся к новым версиям iOS.

В статье, на примере подготовки к iOS 26, вы найдёте пошаговый процесс адаптации к обновлениям системы и узнаете, какие проблемы могут встретиться по пути.

🔖 Приятного чтения!
Please open Telegram to view this post
VIEW IN TELEGRAM
11👍1🔥1
Двигаем списки оптимально

Представьте, что вам нужно реализовать drag&drop список, в котором можно менять элементы местами. Элементы списка хранятся в БД, и мы можем добавить туда поле priority, по которому будет выполняться сортировка.

Можно решить задачу в лоб и просто пересчитывать все приоритеты при перемещении карточки — на небольших списках это даже будет работать нормально.

Но представим, что у вас сотни таких элементов, и вы двигаете последнюю карточку в начало списка. Тогда придётся сделать 100 записей в БД — звучит не очень оптимально 🤔

Как сделать лучше?

Можно заполнять поле priority не с шагом 1, а, например, с шагом 100.

🟢Тогда при перестановке элемента в середину списка нам будет достаточно взять средний приоритет между соседними значениями и обновить только один элемент в БД.

🟢Для крайних элементов тоже всё просто: либо вычитаем шаг приоритета, либо прибавляем.

🟢Но может случиться так, что после многих перестановок разница между элементами станет равной 1, только тогда придётся перезаписать все приоритеты.

Итого: в первом варианте у нас всегда была бы сложность O(N), а во втором, в большинстве случаев O(1), и только в худшем сценарии мы получим линейное время.

А вы бы стали заморачиваться с оптимизацией? Или сделали бы простой вариант?
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥25
This media is not supported in your browser
VIEW IN TELEGRAM
Первый Android Meetup от Сбера: твой план на вечер

28 августа собираемся с Android-комьюнити, чтобы со спикерами из Сбера и Лаборатории Касперского обсудить современные практики разработки, опыт работы с инструментами и подходы к созданию качественных и доступных приложений.

📍 Выбирайте удобный формат участия и регистрируйтесь на лендинге!
Ждём вас очно и онлайн!
9
Путеводитель по каналу

Спустя ровно год канал набрал ещё тысячу подписчиков, спасибо вам, что читаете 🦞

Собрал для вас самые интересные посты по темам, вдруг найдёте что-то полезное для себя:

Compose
Что такое Compose Snapshot
Анимации по стейту в Compose
Проблемы Compose for WEB
Декларативный Bottom Sheet
Управляем курсором в TextField
Compose в React Native
SwiftUI в Compose Multiplatform
Отличия в модификаторах в SwiftUI и Compose
Must-have материалы для изучения Compose

iOS и KMP
iOS библиотеки в Kotlin коде
Собираем iOS приложения без macOS
Ставим iOS приложение из браузера
Как подключить KMP в iOS проект без CocoaPods
Фоновая работа в Android и iOS
Отличия при работе с БД на Android и iOS
Разное поведение Map на платформах
Интероп suspend и async функций
Зачем использовать новый Uuid

Android
Бессмертное приложение
Как сделать плитку в быстрых настройках
Шарим библиотеки между проектами

Корутины
Корутинные рецепты
Статья про нестандартное использование корутин

Библиотеки
Detekt правила для Decompose
Как зашифровать SharedPreferences
Библиотека для декларативного показа Snackbar

Разное
Об авторе канала
Мое первое мобильное приложение
Автоматизации в умном доме
Как опубликовать приложение с VPN в Google Play

#Навигация
Please open Telegram to view this post
VIEW IN TELEGRAM
7🎉285🔥4👍2🤝1
Kotlin Adept Notes pinned «Путеводитель по каналу Спустя ровно год канал набрал ещё тысячу подписчиков, спасибо вам, что читаете 🦞 Собрал для вас самые интересные посты по темам, вдруг найдёте что-то полезное для себя: Compose Что такое Compose Snapshot Анимации по стейту в Compose…»