Мобильное Чтиво
1.6K subscribers
271 photos
43 videos
153 links
Очень серьезный канал про мобильную разработку. Веду канал я — @maxkachinkin
Download Telegram
Сервис автоматизации — это не страшно

Закрываем Podlodka Android Crew 12 постом о самом интересном сегодня!

Сегодня выступал Миша Левченко с докладом про сервисы автоматизации. И вот что самое главное надо знать:

- Не боимся писать сервисы автоматизации — это проще, чем кажется! 🚀

- Пишем на Kotlin. Мы, Android-разработчики, вполне можем сами написать такой сервис на Kotlin.

- Берем Ktor и не паримся. Заходим на Ktor генератор, выбираем, что нужно, и получаем готовый шаблон проекта. 🔧

- Для планирования задач можно юзать Quartz — отличный вариант для cron задач. 📅

И вишенка на торте — Миша зафичерил меня в своем докладе, как видно на картинке! 🎉

А как у вас с автоматизацией? Свой сервис уже написали? 😏

#podlodka #android #automation #Ktor #Kotlin
🔥7👍1
🔥 Kotlin 2 и прощате, Backing properties!

Всегда раздражало, что в Kotlin считалось нормальным делать backing properties, пишешь 2 проперти вместо 1. Выглядело как недодизайн. Но теперь в Kotlin 2 это решено! 🎉
Наглядный пример есть в посте от Android Good Reads.
👍5🤩3
Forwarded from Android Good Reads (Anton Kondratiuk)
Одна из причин перейти на Kotlin 2.0 это уменьшение количества кода ради кода. ExplicitBackingFields, как хороший пример

class SomeViewModel {
val city: StateFlow<String>
field = MutableStateFlow("")

fun updateCity(newCity: String) {
city.value = newCity // обрабатывается как MutableStateFlow
}
}

fun outside(vm: SomeViewModel) {
vm.city // обрабатывается как StateFlow, вызов геттера
}
👍17🔥11👏1
🚀💻 Из джуна в сеньоры за полгода: миф или реальность?

🔥 С таким заголовком будет проходить дискуссия на канале AI4Dev через 15 минут, в которой меня пригласили быть участником!

Если есть время — заходите или смотрите потом в записи.

Мне самому интересно, куда зайдёт дискуссия! 🤔

Как бы вы ответили на этот вопрос из заголовка?

#talk #youtube
😁7🔥2🤡1
This media is not supported in your browser
VIEW IN TELEGRAM
🎨 Главное — чтобы было красиво!

Тесты, шместы, архитектура — это всё прекрасно. Но в итоге главное — чтобы было красиво! Я вот вспомнил одну нашу фичу, где надо было сделать кастомный контрол типа табов, которые плавно анимировались, центрировались на выбранном, а потом обратно схлопывались. Всё на Compose, конечно. 💻

И что вы думаете? Контентные паддинги в LazyRow не помогли, игры с отступами тоже. Даже использование horizontalScroll не дало результата. Пришлось думать дальше. 🤔

А как в итоге сделали? Ну, это можно назвать костылём (или нормальным решением, если вам так больше нравится). Добавили "фейковые" элементы в начале и в конце списка и анимировали их размер. 🙃

Используем LazyRow и делаем первый и последний item просто прозрачные Spacer, чтобы создать видимость отступов. Плавно и красиво анимируем их ширину, и всё! 💫 На самом деле не совсем всё: это тянет за собой много всего, чтобы учитывать эти элементы по-особенному (чтобы не кликались, не анимировались, не участвовали в выборе и т.д.).

Как заметили в комментариях, это создает дополнительные рекомпозиции 🫣, что не может радовать. Такой трейдофф решили взять. Но в итоге всё выглядит плавно, аккуратно, ну и просто красиво! 🌟

В комментах я добавлю скриншот кода и видосик — там видно, как это анимируется и центрируется. 🎥

А у вас какие были проблемы из-за красоты? Поделитесь! 😎

#android #compose #ui #lazyrow
👍15💯4🥰1
⚙️ Kotlin in GitHub Actions ⚙️

Совсем скоро Мобиус 2024 Autumn, и я там выступаю с докладом Kotlin in GitHub Actions. Расширяем горизонты KMP. 😎

Я расскажу, как написать свой кастомный GitHub Action на Kotlin/JS: что для этого нужно, как всё работает и какие подводные камни могут встретиться.

Если вы никогда не писали кастомный GitHub Action на Kotlin/JS, но вдруг захотели до моего доклада, то, уверен, потратите прилично времени, чтобы разобраться. 🕵️‍♂️

А после моего выступления вы точно сделаете это намного быстрее! 🧠

А вы писали когда-нибудь на Kotlin/JS?

#android #kmp #kotlinjs
🔥11👍3
🤩 Билет на Mobius! 🤩

Я разыгрываю билет на Mobius 2024 Autumn!

Условия участия просты: написать сообщение под этим постом, какой доклад вам больше всего хочется послушать!

Чтобы выиграть не обязательно писать, что мой доклад Kotlin in GitHub Actions самый интересный 😅 Победит чистый рандом! 🎰

Билет может быть как онлайн, так и оффлайн, как вы захотите.

Итоги подвожу в четверг 10 октября! 📅

#mobius
🔥9👍4😁1
“Смотрим” на Compose через <clinit>

Я хочу вам рассказать про 2 метода: <init> и <clinit>. 👇

<init> — это метод-конструктор. Каждый раз, когда мы создаем новый объект через new, JVM вызывает этот метод, чтобы инициализировать объект и его поля. 📦

<clinit> — это статический инициализатор класса. Этот метод вызывается, когда класс впервые загружается в память. И да, это происходит только один раз при первой загрузке класса. 🔄

Когда и кем вызывается?

JVM автоматически вызывает <clinit> при первой загрузке класса в память.
А вот <init> вызывается каждый раз, когда вы создаете новый экземпляр класса.

Теперь к интересному! 💡

Смотрите на картинку. Здесь показан запуск Compose-экрана, когда он открывается впервые в приложении, и до этого никакие Compose-функции не были вызваны.

На диаграмме чётко видно, как активно срабатывают <clinit> методы. Это часть подсвечена. Это как раз и есть свидетельство того, что Compose — это unbundled library. Я как-то рассказывал про это на Mobius, но эта картинка показывает это наглядно.

А вот при повторном запуске? Никаких <clinit> уже нет. 🎯

Да, конечно, тут не только классы Compose, но если порыться в методах, то большинство из них типо такие:
androidx.compose.foundation.layout.RowKt.<clinit>
androidx.compose.foundation.layout.ColumnKt.<clinit>


Вывод: При первой загрузке Compose через класс-лоадер загружается больше количество классов. 🚀

P.S. Не забывайте, в закрепе розыгрыш БЕСПЛАТНОГО билета на Mobius! 🎁

#android #compose #kotlin #jvm
👍8🔥6
📜 Ваш любимый логгер! 📜

Мы в своих Android-проектах давно логируем через SLF4J/Logback Android. Да, да, это тот самый проверенный временем логгер.

🎯 У него есть плюсы: Надежный (не считая истории с CVE-2023-6481, но там речь про классический, а не android), стабильный, с хорошей поддержкой форматов логирования. Работает без сюрпризов, настройки для форматирования и фильтрации логов. В общем по функционалу всё нравится.
Но есть главный минус: Увы, только для Android. Не подходит для KMP, да и по гибкости проигрывает более свежим решениям.

Я понимаю, что SLF4J/Logback — это не самый гибкий и современный подход, особенно если ваши проекты уже идут в стороны Kotlin Multiplatform.

А как у вас с логированием дела обстоят? 😎

- Logback Android, как у нас?
- Может быть Timber?
- Или уже думаете о будущем и логируете с помощью 🦸‍♂️Napier или 🐸Kermit?
- Или, может, у вас есть свой подход?

Поделитесь, очень интересно узнать! 👀

P.S. Не забывай! В закрепе БЕСПЛАТНЫЙ билет на 🟢Mobius🟢! 🎁 Успейте до четверга!

#android #kmp #logging
5🤓1
🔥 Топ ожидаемых докладов 🔥

Недавно я запустил конкурс на бесплатный билет на Mobius (у вас еще остался 1 день, завтра днем крутану рандомайзер 🎰), и я попросил написать, какие доклады вы ждете больше всего. Кто-то написал 1 доклад, кто-то несколько. Я учел и посчитал все упоминания.

🎤 И вот самые ожидаемые доклады по версии подписчиков Мобильное чтиво:

Первое место разделили:

🥇 Не два байта переслать: эмуляция бесконтактных карт на мобильных устройствах
Павел Васильев, Positive Technologies

🥇Что не так с мобильными сервисами в Android и iOS
Кирилл Розов, Android Broadcast

🥇Kotlin in GitHub Actions. Расширяем горизонты KMP
Максим Качинкин, Dodo Engineering
Эти доклады набрали по 5 голосов.

Могу предположить, что мой доклад упоминали, потому что я веду этот канал 😏. Поэтому вот доклады, которые на 2м месте — они набрали по 4 голоса. Тоже очень ожидаемые!

Второе место:

🥈 Compose и SwiftUI: найди 10 отличий
Алексей Панов, Контур

🥈 Опасности в Android: уязвимости и защитные меры
Юлия Стекачева, Райффайзен Банк

🥈 Предпринимательство для инженера: как запустить свою компанию
Евгений Мацюк, MarathonLabs

🥈 Суперапп с чистого листа
Сергей Балалаев, Ozon

Все вышеперечисленные доклады я тоже хочу посмотреть. Но я еще добавлю от себя, что мне интересно.

Я жду вот эти 2:

🚀 Заезжаем в KMP. Но какой ценой?
Денис Александров, Яндекс 360

🚀 Последнее слово в Android-навигации
Данил Колесников, Дзен

#Mobius2024 #Android
5👍2🔥2
This media is not supported in your browser
VIEW IN TELEGRAM
🔥15👍1😁1
🤣 Пятничный мем 🤣

Сегодня выступил на Mobius на online дне. Про само выступление напишу потом. Сегодня просто легкий пятничный пост.

Как я готовился к выступлению с визуальной части. Есть 3 момента:

- Мне нравится рассказывать стоя. Так я чувствую себя более динамично и бодро. 💪
- Хочется, чтобы фон был красивый. 🎨
- У меня нет стола с регулировкой высоты, поэтому приходится что-то придумывать. 🤔

Для этого я нашел стену, обустроил её как надо (бахнул на телек красивую картинку), а чтобы встать рядом с ней стоя, пришлось соорудить конструкцию из того, что попалось под руку (включая коробку из-под обуви). И, конечно, надо поставить кружку воды, мобилу и прочее. 📱☕️

И получился мем:
Frontend - Backend 😄

#mobius #meme #пятница
😁29🔥6👍4🤣41
📅 Как проходит мой рабочий день 🏃‍♂️

Вышла статья из рубрики “День с экспертом” на SkillFactory Media. Там я рассказываю про свой типичный рабочий день.

Из интересного и про мобильную разработку я рассказываю, что:
• у нас есть правило на короткие PRы 📝
• мы работаем по Trunk-Based Development 🌳
• я люблю парное программирование, но удается применять его редко 👨‍💻👩‍💻
• подставка под ноут — это маст 📦
• каждый день кормлю уличных котов 🙂

Заголовок и тон статьи может вызвать подозрение на тупые понты или что я собрался продавать мастер-классы “Эффективная эффективность: успевайте всё как я”. Знайте, такого намерения не было. 😅

💬 Мне интересно, а что у вас любимое в вашем рабочем дне? Или наоборот, что вас бесит?
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥2🍌2😁1🙈1
🇦🇲 Увидимся на DevFest в Ереване 🇦🇲

В это воскресенье, 20 октября, в Ереване пройдет DevFest Armenia 2024!

Я буду выступать там (да, оффлайн) с докладом:
Compose as an Unbundled Library: What It Means for Your App.

Подписчики этого канала знают, что на эту тему я делал посты здесь и ни раз. Вот теперь расскажу целиком вслух:
🐣 Что значит unbundled library
📏 Как замерять UI перфоманс
⏱️ Как можно оптимизировать Compose, если все-таки столкнулись с долгой первой загрузкой

Если вдруг кто есть в Ереване, го на DevFest, пообщаемся!

#devfest #yerevan #compose
🔥122👍1
🎨 Зато Compose не скован версиями Android 🤖

Я пару раз уже писал на эту тему Compose как Unbundled Library. Сейчас напишу в последний раз (надеюсь 😅). Но теперь с конкретикой и расскажу, чем это хорошо или плохо.

В отличие от Compose, все классы View уже лежат в памяти нашего процесса еще до того, как вы вообще успели запустить приложение!

Когда же они туда попали? 🧠

Ответ — еще до старта вашего приложения! При инициализации процесса Zygote. 🧬

Есть такой файл, он называется preloaded-classes и лежит вот тут:
/system/etc/preloaded-classes.

В этом классе строчка за строчкой записаны все полные имена классов Android фреймворка. Их там больше 17k! Включая, конечно же, классы системы View! 📜

Потом в методе preloadClasses мы читаем этот файл, строчку за строчкой, и загружаем классы в память процесса!

Вот так! Еще до ващего Application::onCreate, до контент провайдеров, до того как ваш процесс форкнется от Zygote, в нем уже всё будет загружено!

У Compose такой магии нет. Но отсутствие предзагрузки позволяет нам подключать разные версии Compose и обновлять его гибко.

Поэтому Compose не скован никакими версиями Android фреймворка. Мы не пишем с вами код, типа:
VERSION.SDK_INT >= VERSION_CODES.TIRAMISU

для компоуз кода.

Отвечая на вопрос чем это плохо 👎:
- Compose требует времени на загрузку в рантайме
Чем это хорошо 👍:
- Наконец-то есть гибкость и свобода!

💬 Вам нравится гибкость? Или вы бы предпочли предзагрузку вместе с Android фреймворком?

Кстати, на фото — это как раз я на DevFest Armenia на этих выходных, объясняю вот этот самый момент про Zygote и preloaded классы. 📸

#Compose #DevFest
👍27🔥153
This media is not supported in your browser
VIEW IN TELEGRAM
🚀 Как лучше работать с OTP?

Чтобы автоматически обрабатывать SMS, мы в Drinkit используем SMS Retriever API от Google.

Это популярный инструмент для такой задачи. Кто немного не знаком с ним я перечислю основные моменты:

1️⃣ Не нужны разрешения. Чтобы использовать это API, не нужно запрашивать у пользователя доступ к SMS. SmsRetriever даёт нам 5-минутное окно, в течение которого система ожидает входящее сообщение с кодом.

2️⃣ Безопасность. SMS Retriever API ожидает хеш приложения, который зашивается в SMS. Это значит, что у нашего приложения будет доступ только к “нашим” SMS-кам.

3️⃣ Удобство для пользователя. Если всё сделать, то код подтягивается автоматически, и пользователю не нужно вручную копировать его из сообщения. 👌 Прямо как на видео, смотрите!

Конечно, это не единственный способ. Есть и другие варианты:

- Использовать One-tap SMS verification API.
Там будет дополнительный Bottom Sheet с подтвеждением. Но, если честно, я такой встречаю крайне редко.
- Вообще не автоматизировать — пользователь сам вводит код. Периодически я встречаю такие приложения.
- BroadcastReceiver или Content Provider — старые подходы, которые требуют больше пермишенов и возни с кодом.

Однако, я заметил, что не все приложения используют SMS Retriever API. Например, видел что им пользуются Uber или Яндекс Такси. Но далеко не все приложения. 🤔 Интересно, почему?

А вы что используете для обработки OTP у себя? Делаете через SMS Retriever API или выбираете другой путь? Стоит ли мне подробнее расписть про SMS Retriever API? Делитесь в комментах! 😎

P.S. Мартышки, это не часть нашего UI, просто я скрыл номер телефона ☺️

#android #smsretriever #otp
👍24🤔21
🎃 Чего я боюсь 🎃

В Хеллоуин принято пугать друг друга, в шутку и не очень. Давайте поговорим о том, что нас пугает в разработке!

Вот мой топ 3 самых больших страха!

1️⃣ Случайно нажать Sync Projects With Gradle Files вместо нужной кнопки... и просто замереть в ужасе. 🧙‍♂️

2️⃣ Когда ты iOS-разработчик, а тебе говорят: "Сделай как на Android." 🧛‍♂️

3️⃣ Идешь читать доку "Migrate apps to Android 13/14/15" (подставь любую версию) 🕸️

Напишите в комментах, а какие у вас страхи? Если не боитесь! 👻
😁16👍2
This media is not supported in your browser
VIEW IN TELEGRAM
🇺🇸 Рисуем SVG в Compose Great Again

Сегодня расскажу, как можно нарисовать сложный рисунок в Compose, если у вас есть SVG файл. А именно как распарсить SVG файл в удобные для нас Path и отрисовать их “руками”.

🔍 Парсинг SVG: Мы загружаем SVG файл с помощью XmlPullParser, который читает каждый элемент. В каждом path элементе хранится информация о том, как рисовать фигуру — всё закодировано в атрибуте d. Этот атрибут содержит команды типа "M" (move to), "L" (line to), "C" (curve to) и координаты. Вместе они формируют контур, который и станет нашим рисунком.

🛠️ Конвертация Path: Здесь проблема. В Compose пока нет метода для декодирования пути напрямую из d атрибута SVG.

Но мы сделаем конвертацию Great Again! Мы сначала создаём старый добрый Path из androidx.core.graphics (через метод createPathFromPathData), а потом конвертируем его в Compose Path с помощью asComposePath. Немного костыльно, но работает.

Теперь, когда мы всё распарсили и конвертировали, можем просто отобразить это в Compose.

Я выложил пример на GitHub, где вы можете посмотреть, как это работает. В этом проекте пярмо то, что изображено на видосе, какая-то карта и какие-то непонятные области.

P.S. Да, нажатия сделаны не совсем идеально — попадание внутрь Path осуществляется по bounding box, а не точно по форме. Но это уже отдельная задача, а здесь у нас фокус на отрисовке! 😎

💬 А что интересного вы рисовали в Compose?

#compose #svg
🔥21😁7👍3
🚀 Используй ScatterMap, если ты помешан на производительности

Обожаю Romain Guy и его выступления. Недавно смотрел его видео Exploring Kotlin Performance на канале Code with the Italians 🎥

Он рассказывает, как писать код на Kotlin так, чтобы он был максимально производительным. Показывает во что компилируется Kotlin и анализирует это.

Мы можете мне возразить: зачем мне это? Ведь моё дело написать читаемый код, а дело разработчиков компиляторов сделать так, чтобы он работал быстро!

Но. Если вы хотите написать супер производительный UI и особенно на Compose, то тут каждая мелочь может иметь значение!

Я приведу один пример из видео: Map vs ScatterMap.

Если вы используете HashMap, то в скомпилированном коде будет много вызовов функций и аллокаций. И даже если GC у нас больше не в мейн треде, то лишние аллокации все равно не желательны для супер производительного UI. 🧹

Так вот, в таких случаях можно использовать ScatterMap. Эта штука ведет себя почти как Map, но работает с ключами по-другому и требует гораздо меньше аллокаций. Это значит, что производительность становится выше, особенно в UI-интенсивных задачах.

Но стоит учитывать пару нюансов:
- ScatterMap не потокобезопасен 🕵️ (просто держите это в уме)
- он не очень эффективен, если вы часто удаляете элементы или работаете с огромным количеством данных.

💬А вы когда-нибудь заморачивались, чтобы использовать ScatterMap? 🤔
Разобрать ли мне более подробно ScatterMap?

#ui #performance #scattermap
👍14🔥41