Android Broadcast
14.6K subscribers
3.8K photos
391 videos
11 files
6.26K links
Подборка новостей и статей для Android разработчиков.

Реклама и связь с автором @ab_manager

РКН https://abdev.by/rkn_tg_ab #MQRZR
Download Telegram
🤖 На Google I/O 2026 Google официально переименовала Android из операционной системы в "intelligence system"

Самое интересное для разработчиков - AppFunctions. Это experimental preview API + Jetpack библиотека, которые позволяют приложению стать on-device MCP (Model Context Protocol) сервером. Агенты вроде Gemini смогут обращаться к функциям приложения через стандартный протокол, без скрейпинга UI. Для отладки выпустили тест-агент, для раннего выхода в production открыта форма early access.

По on-device моделям: ML Kit GenAI APIs теперь работают с Gemini Nano 4 (preview). Prefix Caching уже доступен — кеширует промежуточное состояние LLM для повторяющихся частей промпта, снижает время инференса. Structured Output API скоро - типизированные объекты на выходе вместо свободного текста.

Firebase AI Logic Hybrid Inference добавляет явный контроль маршрутизации — режимы PREFER_ON_DEVICE, PREFER_CLOUD, ONLY_ON_DEVICE, ONLY_CLOUD прямо в коде. ADK for Android в первой версии позволяет строить multi-agent workflows с оркестрацией между on-device и cloud моделями.

Ещё есть A2UI + Compose Renderer: агент "говорит UI", Compose рендерит ответ как нативные компоненты. Пока чистый эксперимент, но направление понятное. Вот для чего делается Compose BDUI

Меня больше всего интересует AppFunctions. MCP как стандарт уже работает в десктопных агентах, и Google принесла это на уровень ОС — правильное решение. Вопрос в том, насколько быстро экосистема это подхватит за пределами флагманских приложений и почему не подключать сервер к этому, я использовать интеграцию через приложение

🔗 Источник - Android Dev Blog

#Android #AndroidDev #GoogleIO #AI
Please open Telegram to view this post
VIEW IN TELEGRAM
👎61🔥1054👍4👏3
🤖 Google анонсировала ADK for Android 0.1.0 вместе с ADK for Kotlin

ADK (Agent Development Kit) - это open-source фреймворк для AI-агентов, и теперь у него есть Android-артефакт с поддержкой on-device моделей.

Ключевая архитектурная идея: облачный оркестратор ведёт диалог с пользователем и координирует работу. Когда нужно обработать приватные данные - документы, брони, личные файлы - он делегирует subagent'у, который работает на устройстве через ML Kit GenAI и AICore. Данные за пределы устройства не уходят.

В стек входят LLM-агенты, sequential agents, MCP tools, session state и long-term memory через Memory service, OpenTelemetry для наблюдаемости.

Можно использовать три варианта моделей:
👉 ML Kit GenAI для on-device Gemini Nano
👉 Firebase AI Logic для облачного Gemini
👉 Google GenAI для быстрого прототипирования.

‼️ ВАЖНО: версия 0.1.0, статус "В активной разработке". Это очень ранний экспериментальный релиз, не для продакшна.

Архитектурный паттерн с разделением на облачный оркестратор и on-device агент выглядит разумно - именно так я бы и хотел видеть подобный инструмент. Но внедрять в прод рано.

🔗 Источник Android Dev Blog

#Android #AI #Gemini
👎34👍1321
🤩 Готовишься к OOD-собеседованию? Новая книга в помощь

10 июня в издательстве «Питер» выходит «Object Oriented Design. Подготовка к сложному интервью» Алекса Сюя — автора бестселлера про System Design и бывшего инженера Twitter, Apple, Zynga и Oracle.

🤐 Внутри:
🔗 Чёткая 4-шаговая схема решения любой OOD-задачи
🔗 Глубокий разбор ООП и принципов SOLID
🔗 14 готовых систем: парковка, кинотеатр, банкомат, лифты, ресторан и др.
🔗 11 реальных задач с интервью с подробным разбором решений
🔗 133 диаграммы архитектур и процессов
🔗 Паттерны проектирования + советы по коммуникации с интервьюером

🎁 Промокод broadcast — скидка 5% на книги издательства "Питер"!

#реклама
Please open Telegram to view this post
VIEW IN TELEGRAM
👎13👍102
🤖 Google прилагает много усилий, чтобы сделать разработку адаптивных интерфейсов проще: библиотеки, поддержка в IDE, инструменты и пр. Понятно, ведь растет популярность складных устройств. Компания старается расширить Android за пределы смартфона, а складные смартфоны набирают обороты популярности (хоть и медленно).

‼️ Android 17 вскроет все недостатки ваших приложений на планшетах и складных смартфонах, потому что там теперь будут игнорироваться ограничения окон приложений.

В ближайших постах я пройдусь по основам адаптивности интерфейса, а пока вы можете изучить:
👉 Обзор экосистемы адаптивности от Google для Android
📹 Adaptive development for the expanding Android ecosystem
📹 Make your UI adaptive with Android Studio's AI agent
👉 Build adaptive apps
👉 Критерии качества адаптивных приложений (3 уровня)

#Android #AndroidDev #UI #Foldable #Планшет
Please open Telegram to view this post
VIEW IN TELEGRAM
👍35👎71
🤖 R8 Configuration Analyzer - удобный способ изучить как ваша конфигурация R8 влияет на итоговый код в сборке

Keep rules из сторонних библиотек часто написаны с запасом: разработчик библиотеки не знает, как именно вы её используете, и кладёт широкое -keep class com.library.** { *; }. R8 видит это и выключает оптимизацию для всего пакета, даже если вашему приложению нужны оттуда три класса. AGP 9.3.0-alpha05 добавил инструмент, который это наконец показывает с цифрами.

Configuration Analyzer генерирует HTML-отчёт, в котором по каждому keep rule и по каждой библиотеке видны три метрики:
👉 Shrinking score - процент кода, доступного для удаления неиспользуемых классов и методов
👉 Optimization score - процент кода, доступного для инлайнинга, мёрджинга классов и прочих R8-оптимизаций
👉 Obfuscation score - процент кода, доступного для обфускации имён

Начиная с AGP 9.3.0-alpha05 отчёт генерируется автоматически в build/outputs/mapping/release/configanalyzer.html при каждом билде с квлюченной минификацией. Для AGP 9.2 и ниже нужно при запуске ./gradlew assembleRelease передать системный флаг com.android.tools.r8.dumpkeepradiushtmltodirectory с путём до папки куда сохранить отчет.

Помимо широких правил анализатор выделяет ещё два типа мусора:
👉 unused rules, которые не матчат ни один класс в текущем билде (обычно появляются после рефакторинга)
👉 subsumed rules, когда одно широкое правило перекрывает другое и делает его бессмысленным.

‼️ ВАЖНО: требует R8 9.3.7-dev, который идёт в комплекте только с AGP 9.3.0-alpha05. Это ранняя alpha. На продакшн-сборки без тщательной проверки не стоит.

Это первый инструмент с конкретными цифрами по влиянию сторонних библиотек на R8. Раньше это была область догадок и ручного анализа mapping-файлов. Теперь можно прийти к мейнтейнеру с отчётом и показать: вот твоё правило, вот 35% заблокированной оптимизации у нас в проекте. Круто если такой отчет можно будет получить как XML/JSON чтобы встраивать в другие инструменты.

#Android #AndroidDev #R8 #Performance #agp #Произодвительность
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍46👎31
🤖 ⚙️ Адаптивность под разные экраны — одна из тех вещей, которые откладывают до последнего. А когда приходит требование поддержать планшет, начинается боль. Хотя в Compose это решается в несколько строк.

GridCells.Adaptive сам рассчитывает колонки под доступное пространство — ничего не нужно задавать вручную:

LazyVerticalGrid(
columns = GridCells.Adaptive(minSize = 160.dp),
modifier = Modifier.fillMaxSize()
) {
items(list) { ItemCard(it) }
}


Но почти всегда забывают про пагинацию. pageSize хардкодят, и это ломает всю адаптивность. На планшете с 4 колонками те же 20 элементов — это 5 строк. Пользователь упирается в конец страницы раньше чем успел проскроллить.

Правильно — считать pageSize от реального числа колонок:

BoxWithConstraints {
val columns = (maxWidth / 160.dp)
.toInt().coerceAtLeast(1)
val rows = (maxHeight / 120.dp)
.toInt().coerceAtLeast(1)
val pageSize = columns * rows

val items = remember(pageSize) {
Pager(PagingConfig(pageSize = pageSize)) { MyPagingSource() }
}.flow.collectAsLazyPagingItems()

LazyVerticalGrid(
columns = GridCells.Adaptive(minSize = 160.dp)
) {
items(items.itemCount) { ItemCard(items[it]) }
}
}


На смартфоне выйдет ~10 элементов, на планшете ~30. Никаких магических чисел — только математика от реального пространства.

Самый хороший пример тут - галерея. Они показывают адаптивную сетку контента и имеет возможность настройки другого расположения элементов

🔗 Lazy lists and grids — Android Developers

#Compose #Android #AndroidDev #Ui #Adaptive #Адаптивность
Please open Telegram to view this post
VIEW IN TELEGRAM
👍548👎7🎉3
🤯 Android 17 умеет убивать ваше приложение молча. Без стектрейса. Разбираемся. И ЭТО БЕЗ КЛИКБЕЙТА

Начиная с Android 17, появился системный MemoryLimiter — лимит памяти на процесс, привязанный к общему объёму RAM устройства. Превысил лимит — процесс убит. Без exception, без стектрейса.

Как это выглядит:
👉 причина завершения в ApplicationExitInfo = REASON_OTHER
👉 в описании строка "MemoryLimiter:AnonSwap"
👉 в Crashlytics этого НЕ будет: это не краш, а системное убийство процесса

И сразу разрушим главное заблуждение: это НЕ про heap size.

getMemoryClass() и largeHeap ограничивают только Java-кучу — объекты под управлением ART. Превысил и получишь OutOfMemoryError со стектрейсом, который ловится. А новый MemoryLimiter считает другое - анонимную память ВСЕГО процесса:
👉 битмапы (с Android 8 их пиксели в нативной памяти, в Java-куче их нет)
👉 нативные библиотеки, медиакодеки, Skia
👉 веса on-device ML/LLM моделей

Всё это в getMemoryClass() не видно. Можно сидеть втрое ниже heap-лимита, никогда не словить OOM — и всё равно быть убитым, потому что суммарная нативная память процесса вылезла за порог. getMemoryClass и OOM — про Java-кучу. MemoryLimiter — про весь процесс. Это два разных предохранителя, и старый про новый вам ничего не скажет.

Важные оговорки, чтобы не было паники на пустом месте:
👉 в Android 17 лимиты заданы консервативно: цель — экстремальные утечки и выбросы, а не нормальные приложения
👉 включены только на части устройств
👉 конкретных чисел Google не публиковал. Реальный лимит своего девайса можно снять командой: adb shell am memory-limiter status

В зоне риска тяжёлые сценарии на устройствах среднего и бюджетного сегмента.
Уже есть задокументированный случай на бете — крупная on-device модель Gemma падала на Pixel 6a с 6 ГБ RAM именно из-за MemoryLimiter. 6 ГБ — это уже не бюджетник. Java-куча там небольшая, а нативка с весами модели — гигабайты в RAM.

Два мифа, которые гуляют по сети и которые повторять не надо:
👉 НЕТ подтверждения, что система шлёт «вежливое предупреждение» перед убийством
👉 НЕТ официального «дедлайна для разработчиков 30 июня». Google его не объявлял

Это первый раз, когда дисциплина по памяти не совет, а правило от ОС. Сейчас лимиты мягкие, но направление одностороннее — закручивать будут, а не отпускать. И самое неприятное тут не сам лимит, а его невидимость: пользователи будут терять сессии, а вы не узнаете, пока специально не начнёте смотреть.

💬 Как вы думаете, связаны ли меры с тем, что оперативка стала дорожать и вставить по 12–16 ГБ стало дорого?

#Android #Android17 #Производительность
Please open Telegram to view this post
VIEW IN TELEGRAM
👎69👍195👏2🎉11
🤖 Google как раз выкатила напоминание как оптимизировать расход памяти в Android приложениях. По сути ничего нового для тех кто уже занимался подобным, а остальным на заметку

#Android #AndroidDev #Производительность #Оптимизация
Please open Telegram to view this post
VIEW IN TELEGRAM
👍37👎71
🔴 Созвон Закрытого Сообщества. Жаркая дискуссия: какой агент лучше. Best practices, ошибки и как работать с ИИ.

Гость — Никита @Nek.12. Один из немногих в русскоязычном сообществе, у кого я реально нашел много интересного для работы с ИИ. Никита не использует Claude Code, Codex или Cursor. Он написал своего агента с нуля. Builder — это CLI-хarness с супервайзером, скиллами, Docker-сэндбоксингом, клиент-серверной архитектурой и возможностью гонять агента автономно сутками. Всё сам. В одиночку.

У нас принципиально разные подходы. Я работаю с Claude Code, активно использую MCP-серверы и верю в это. Никита написал статью "MCP is Deprecated" и считает, что сложные агентные оркестраторы — это микроменеджмент, который мешает модели работать.

Будем разбираться, кто прав. Или оба правы по-своему. Или оба не правы.

Формат — живой разговор, вы можете задавать вопросы в чате прямо во время эфира.

🪙 Стрим пройдет для платных подписчиков на Boosty

#AndroidBroadcast #LIVE
Please open Telegram to view this post
VIEW IN TELEGRAM
👎68🔥323👍3👏31
🤖 В Android Bench добавили модели с открытыми весами: GLM, Kimi, DeepSeek Pro

GLM и KIMI расположились посередине межу Opus 4.5 и Opus 4.6, что лично я считаю очень достойным результатом. Ждем разнос от Fable ?

#Android #Benchmark #AI
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👎21🔥18👍55
This media is not supported in your browser
VIEW IN TELEGRAM
👨‍💻 Новый девайс — это хорошо. Новый уровень комфорта — ещё лучше.

Разработчики знают: иногда главный апгрейд — не новый ноутбук, а удобное место, где ты проводишь по 8–10 часов в день.

С 12 по 21 июня (включительно) Эргостол запустил акцию «Открой просторы выгоды»:

🛒 скидки до -25% на товары для рабочего пространства
скидки суммируются с промокодом -10% ANDROID10

Если давно думали добавить в сетап регулируемый стол, удобное кресло или полезные аксессуары — сейчас хороший момент.

➡️ Собери свой идеальный сетап разработчика: по ссылке
Промокод ANDROID10 действует и на Ozon 🛒

#реклама
Please open Telegram to view this post
VIEW IN TELEGRAM
👎23👍116
🤖 Android CLI 1.0: зачем это нужно, если всё уже есть

В Android-разработке с помощью агентов есть конкретная проблема — инструменты разбросаны:
👉 Хочешь запустить эмулятор — avdmanager
👉 Поставить пакет SDK — sdkmanager
👉 Задеплоить APK — adb
👉 Получить версии зависимостей — отдельный запрос к Google Maven
👉 Получить актуальную информацию по гайдам — Web-поиск или Google Developer Knowledge API

Агент вынужден знать синтаксис каждого, склеивать их через shell-команды и угадывать правильные пути. Android CLI 1.0 — это единая точка входа, которая агрегирует всё это в один инструмент с предсказуемым интерфейсом.

Почему CLI, а не MCP-сервер? Вопрос разумный. Но ответ простой: CLI работает с любым агентом без дополнительной интеграции. Настроил инструмент один раз, и он работает с Gemini CLI, Codex, Antigravity, чем угодно. Никаких зависимостей от протокола, никакого выбора поставщика. Хочешь взять только часть — берёшь только её.

Конкретно для агентов в 1.0 есть три вещи, которые раньше было негде взять:
1️⃣ Скиллы. android init ставит android-cli skill с Android-контекстом, android skills add --all добавляет готовые паттерны под конкретные задачи: CameraX, Perfetto SQL, Adaptive UI, AppFunctions. Агент работает не вслепую.
2️⃣ Анализ экрана девайса/эмулятора. android screen capture --annotate делает скриншот с числовыми лейблами на каждом UI-элементе, android screen resolve переводит лейбл в координаты. android layout отдаёт дерево UI в JSON без скриншота вообще.
3️⃣ Запуск Journeys. Описываешь сценарий словами, агент проходит его на устройстве и проверяет результат.
4️⃣ Поиск по Android-документации.

Можно было бы сделать MCP. Он дал бы более тесную интеграцию, но CLI универсальнее и проще в поддержке с любой стороны инструмента, который должен работать везде — это правильное решение.

#Android #AndroidDev #GoogleIO
Please open Telegram to view this post
VIEW IN TELEGRAM
👍33👎13🔥31
🤯 RuStore тайно ставит MAX без спроса и следит за вами через GPS?

Я скачал свежий билд (версия 1.103.0.3) и вскрыл его сам через jadx, а не пересказал чужую панику. Если коротко: градус угрозы надо сильно сбавить.

Главное, о чём автор смолчал - всё что он описал никогда не происходит в реально жизни из-за технических ограничений в самом Android. Тихая установка MAX и фоновая раскатка любого софта возможны только при системной привилегии установки, которую вендор должен выдать приложению отдельно. И тут важно не спутать: быть предустановленным и быть привилегированным - это разные вещи. RuStore действительно предустановлен на части устройств, но сама по себе предустановка такой привилегии не даёт, и фоновой установки на ней нет. Закон РФ об предустановки не требует привилегий, а только сам факт чтобы приложения были установлены сразу. А если вы поставили RuStore сами из APK или у вас есть Google Play, привилегии у него и вовсе не бывает: лицензия Google для производителей смартфонов не позволяет предустановить второй привилегированный стор. То есть на обычном телефоне принудительный сценарий мёртв ещё до старта.

И показательно: ни автор, ни полторы сотни комментаторов не привели ни одного живого устройства, где хотя бы одно приложение установилось само, в коде самого приложения нигде не защита установка какого-либо приложения.

Поставили RuStore сами? Сбор данных включается только вашими разрешениями: не выдали, отозвали, остановили, удалили. Всё под вашим контролем, а не разработчика приложения.

📄 Подробнее в разборе в лонгрид

Если зашло, накидайте реакций и напишите, чей стор вскрываем следующим тем же способом. Как насчет AppGallery от Huawei?

#RuStore #DeepDive
1👍177👎6496
🐘 Room тихо ломает ваш build cache

Команда прогнала свой браузер (открытый проект на 160 модулей) через открытые Develocity Build Validation Scripts. Скрипты гоняют сборку в разных условиях и показывают, какие задачи зря выполняются заново вместо того, чтобы взяться из кеша.

Главная находка про Room. Пути экспорта схем были заданы абсолютными, значит на каждой машине (ноутбук разработчика, CI-агент) получался свой input и свой ключ кеша. Любая сборка на другой машине била мимо. Лечится переходом на Room Gradle Plugin, который держит относительные пути. После фикса в эксперименте с разными путями на диске выполняемых задач стало 27 вместо 440.

😁 Вторая находка про Dagger. Либа генерила классы с непредсказуемым порядком методов: один и тот же исходник на двух CI-ранах давал побайтно разный вывод и промах по кешу. Апгрейд до Dagger 2.53+ с детерминированным выводом вернул в кеш 1619 задач. Опять же важность обновления до свежих версий.

Цифрами по статье манипулируют знатно. Заголовочные 57% относятся к лучшему локальному сценарию: сборке в git worktree после CI. Сквозной выигрыш по реальному CI скромнее, 19% на полном пайплайне с тестами и 39% на сборке debug APK. Инструментальные и Firebase-тесты не кешируются в принципе, поэтому потолок там ниже. Но даже из этого уже есть простые оптимизации, которые стоит проверить.

🔗 Источник - статья на Gradle блоге

#android #gradle #room #buildcache #dagger
Please open Telegram to view this post
VIEW IN TELEGRAM
37👍21👎32🔥2
Forwarded from Compose Broadcast
This media is not supported in your browser
VIEW IN TELEGRAM
⚙️ Compose Navigation Graph: вся навигация приложения интерактивной картой прямо в Android Studio

🐱 Плагин от skydoves (Jaewoong Eum). Аннотируешь экраны @NavDestination, @NavEdge, @NavGraphRoot, KSP статически собирает граф, а IDE-плагин рисует карту: каждый экран отрендеренной @Preview-миниатюрой через Layoutlib, без эмулятора. Переходы стрелками, двойной клик прыгает в исходник, граф мёржится по всем модулям. Канвас редактируемый — тянешь связь от экрана к экрану, и плагин сам вписывает @NavEdge в код.

Работает с Navigation 3, Navigation 2 и даже голыми Activity. KMP из коробки: аннотации в commonMain, есть сэмпл на KotlinConf-приложении (26 экранов, 36 переходов).

Бонусом .nav baseline по аналогии с apiDump/apiCheck: navCheck валит сборку, когда граф разъезжается с закоммиченным базелайном.

#Compose #AndroidStudio
Please open Telegram to view this post
VIEW IN TELEGRAM
👍70🔥147👎51
Forwarded from Claude AI Dev Broadcast
🪙 Хотел уйти с Claude Code, а Claude Design затянул ещё глубже

Девятый выпуск ИИ-дневника. Садился записывать про то, как слезаю с Claude Code на что-то другое: открытые модели, китайцев, локальный запуск. За неделю экспериментов вышло наоборот: подсел на подписку ещё сильнее, и виноват в этом Claude Design.

Внутри разбираю честно: почему меня не убеждают «у меня на нём лучше выходит» и «он дешевле» и какая метрика тут вообще единственная осмысленная. Чем реально держит Claude Design (под него я снёс Figma) и чем он отличается от того же Claude Code на тех же моделях под капотом. И зачем при всём этом я продолжаю смотреть на MiniMax M3, DeepSeek V4 и своё железо.

⚠️ Отдельно про то, что пугает: vendor lock-in и сценарий, где внешние модели в какой-то момент просто перекрывают сверху.

🪙 Весь выпуск смотреть на Boosty

Все выпуски дневника тут

#AI #ClaudeCode #ClaudeDesign
Please open Telegram to view this post
VIEW IN TELEGRAM
👎48👍1021
🤖 Android XR Developer Preview 4: можно потрогать без железа

Google выпустили Developer Preview 4 XR SDK. Главное, что снижает порог: XR Emulator встроен в Android Studio, итерировать можно без Samsung Galaxy XR в руках.

Для мобильных разработчиков добавили нормальный способ расширить существующее приложение на display glasses. Jetpack Projected получил Device Availability API — привязывается к стандартным Android Lifecycle-состояниям, апп адаптируется к очкам нативно. Ускорить переезд помогает Android CLI с display glasses skill — специализированные скиллы, которые делают UI на Compose Glimmer по паттернам Google. Сам Glimmer в этом превью обновили под прозрачные дисплеи: читаемость текста и touchpad-навигация.

Для game dev: Unreal Engine и Godot теперь официально поддерживаются наряду с Unity. Вместе с ними выпустили Android XR Engine Hub под Windows — real-time тест прямо во viewport движка.

Открылась Android XR Developer Catalyst Program: пре-релизное железо (display glasses + wired XR), поддержка и помощь с запуском на Google Play. Заявки принимают прямо сейчас.

🔗 Источники - android-developers.googleblog.com

#AndroidXR #Jetpack #Android
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9👎32
🤖 Миграция навигации hh.ru: 400+ экранов, Modo и feature toggle на переключение реализации

В hh.ru рассказали, как переезжали с Fragment-навигации на Compose + Modo в двух приложениях: 400+ экранов, 70 диплинков, 14 команд. Миграция идёт с 2022 года — и в июне 2026 ещё не завершена.

Modo выбрали за UDF-подход (состояние всей иерархии экранов — обычные данные, переходы — функция от состояния) и потому что разработчик Игорь Кареньков работает внутри hh.ru — можно дорабатывать без ожидания апстрима. Это же стало и первой граблей.

Ключевое решение для глобальных контейнеров: абстракция NavScreen с двумя реализациями — Fragment и Modo Screen, роутер выбирает через feature toggle в рантайме. Это позволило раскатывать переезд через A/B и не стопорить продуктовую разработку. При первой раскатке словили краш в ComposeView, продуктовые метрики просели — остановили, починили, раскатили снова. Без feature toggle был бы хотфикс-релиз.

Три реальные грабли:
👉 Слишком ранний выбор незрелой библиотеки — вложили много времени в доработки самой Modo
👉 Три параллельные миграции одновременно (View→Compose, Fragment→Modo, редизайн) — создали жёсткие зависимости и замедлили продуктовую разработку
👉 Старт без стратегии и метрик — месяцы хаоса, пока не завели дашборд с прогрессом

Если планируешь похожий переезд — там есть что взять.

#Android #Compose #Навигация
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👎28👍131👏11