Telegram Web
​​Фидбек о канале. Пожалуйста не проходите мимо этого поста.

Всем привет. Это @al_gorshkov, автор этого канала и мне нужна ваша помощь.

Мне супер приятно получать от вас обратную связь в личных сообщениях. Это мотивирует и даёт понимание того, что то, что ты делаешь — не зря. И сейчас мне хотелось бы чуть больше понимать, в какую сторону двигаться дальше.

Я создал небольшую форму с вопросами о Telegram и YouTube каналах. Пожалуйста, ответь на вопросы, ведь всё анонимно, а заполнение займёт буквально 2 минуты. А мне даст мотивацию радовать вас еще более качественным контентом на канале. 🤝

Давайте вместе сделаем Android Live ещё лучше!
​​KMM, Swift UI и Jetpack Compose
#compose #kmm #crossplatform

Мы с вами уже не раз обсуждали Jetpack Compose на канале, и даже провели шикарную live-coding сессию, которую можно посмотреть тут.

Кроме просто замены xml-подхода в нативной разработке, Compose отлично стыкуется с KMM и UI-слоем для Android. Ну а для UI-слоя на iOS подходит Swift UI, который тоже является декларативным фреимворком.

Чтобы попробовать такой подход, есть хорошая статья, где по шагам описывается создание простого проекта с использованием описанных выше технологий. Для архитектуры автор хочет использовать MVI, хотя сейчас там только один экран, который сделан без архитектуры.

В любом случае, статья даёт возможность пощупать классные технологии. А запустить приложение, написанное при помщи Kotlin на iOS — бесценно.😁
​​Как сделать адаптеры в RecyclerView лучше?
#kotlin #recyclerview

При написании стандартных адаптеров в RecyclerView, мы часто сталкиваемся с дублированием кода. Особенно это заметно при использовании разных ViewType. Думаю, что многим знаком подобный код:

if (things.get(position) is Duck) {
return TYPE_DUCK
} else if (things.get(position) is Mouse) {
return TYPE_MOUSE
}


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

Существует несколько способов улучшения работы с адаптерами:

1️⃣ Использование layout в качестве идентификатора. Стоит помнить, что layout — это уникальный int, который можно использовать в качестве идентификатора. В этой статье автор предлагает использовать TypeFactory, где можно перечислить всю логику работы с идентификаторами для адаптера, и в случае добавления нового элемента – просто дописать строку в этой Factory. Хороший подход, который можно улучшить и использовать без добавления библиотек.

2️⃣ Использование Delegate для описание логики ViewHolder. Второй подход схож с первым. Можно прописать всю логику для работы с ViewHolder в одном классе Delegate. Потом просто регистрировать подходящие делегаты для нужного адаптера, не думая про имплементацию. Почитать подробнее про подход можно тут и уже есть библиотека, которую стоит изучить прежде чем затягивать к себе в проект.

3️⃣ Использование библиотек. Во втором подходе уже был описан пример созданной библиотеки, но кроме неё есть ещё их огромное множество. На мой взгляд, удачная библиотека описана в этой статье и называется Kiel. При помощи Kotlin DSL наш адаптер становится компактным, а кроме этого мы можем использовать библиотеку как с Paging Library, так и с Diff Utils. Стоит обратить внимание и применить подобный подход для своих приложений, если вам нравится DSL.

А как вы улучшаете свои адаптеры?
​​Миграция с SharedPreferences на Jetpack DataStore
#jetpack

Новая библиотека от Google призвана заменить уже давно знакомую библиотеку для хранения небольших данных — SharedPreferences.

Она существует в двух версиях: Preferences DataStore и Proto DataStore. Первая — даёт возможность хранить и получать доступ к данным по ключу, не требует предварительной схемы данных и не предоставляет type safety. Вторая — требует предварительную схему данных через protocol buffer, но при этом предоставляет type safety.

Почему же Google покусились на давно известную библиотеку? Главная проблема — это то, что при чтении данных из SharedPreferences необходимо открыть файл, где хранятся эти значения, и теоретически это может привести к ANR, если вызвать чтение из UI-потока.
Также в SharedPreferences нет type safety, что может привести к ошибкам во время работы приложения и крашам.

Jetpack DataStore избавилась от этих проблем, а также добавила возможность миграции данных, обработку повреждения данных и обработку ошибок при чтении.

В целом, пока эта библиотека в alpha-версии, поэтому стоит внимательно тащить её в основной проект. Уже есть обёртки для RxJava 2 и 3 версии, если вы используете эти библиотеки. Но если думаете мигрировать — вот краткий гайд, который расскажет, как это сделать. Выглядит достаточно просто, поэтому проблем быть не должно. 🤞🏻
​​Data-классы не нужны в pojo
#comments

В чате канала начали активно обсуждать такую тему: стоит ли использовать data-классы в pojo-моделях?

С одной стороны, переопределяются полезные методы, которые могут понадобиться при работе с pojo-классами. Также, data-класс подходит под определение pojo, так как это чаще всего «классы для данных».

Но ведь чаще всего переопределяемые методы не нужны pojo: мы делаем из них другие модели, которые уже могут быть data-классами. Поэтому, мы лишний раз генерируем несколько ненужных нам методов, которые потом не используем.

Например, если мы получаем json с сервера, то чаще всего нам нужно просто сделать из этого json некую модель (например entity для Room) и сохранить её. Никакие методы из pojo-классов не используются.

А как думаете вы? Обсудим в комментариях под постом.
​​IPC в Android
#theory

IPC — это понятие, означающее межпроцессное взаимодействие. Если мы говорим про это взаимодействие в рамках Android, то подразумеваем или общение между различными приложениями, или общение между разными процессами одного приложения (приложение, где некоторые их его компонентов запущены в разных процессах).
Поделюсь с вами несколькими статьями, которые расскажут про эту недооценённую тему больше.

В Android существует несколько видов межпроцессного взаимодействия:
🔹AIDL — приложение вызывает метод другого приложения на том же устройстве и эта процедура называется иначе – RPC (Remote Procedure Call). Так как эти методы могут быть вызваны многими приложениями одновременно, необходимо помнить про потокобезопасность. Расшифровывается он, кстати, как Android-IDL (Interface Definition Language). По факту, это один из самых базовых методов обмена сообщениями на языке. Понять, как настроить приложение на приём и отправку подобных сообщений можно тут.

🔹Messenger — метод похож на предыдущий, имеет такую же архитектуру. Его легче сделать в приложении, так как он по сути создаёт AIDL за вас, тем самым не заставляет разработчика делать лишнюю работу. Правда, цена такой простоты — меньшая гибкость по сравнению с AIDL. Почитать подробнее можно тут.

🔹Broadcast — наверное, самый популярный из описанных методов. Broadcast может быть отправлен только системой или другим приложением, а приложения могут слушать эти сообщения при помощи BroadcastReceiver. Важно помнить про области видимости ваших Broadcast, их следует настроить в AndroidManifest. Детальнее можно почитать тут.
​​Android 12. Developer Preview
#updates

Тут подвезли свежий Android 12, как раз для нас, разработчиков. Пока только на Pixel, но уже можно ознакомиться со списком нововведений:

▪️SameSite cookie в WebView — для улучшения безопасности WebView, добавили новый тип cookie, раньше он был только в Chrome.

▪️ограниченный Netlink MAC — ещё одна фича в безопасности, которая запрещает использовать реальный mac-адрес в приложениях. Теперь это нововведение будет действовать во всех приложениях, не зависимо от targetSDK.

▪️безопасный экспорт компонентов — защищает от случайного экспорта компонентов приложения. Теперь нужно настроить компоненты в манифесте, если вы хотите сделать их видимыми для других приложений. Стоит проверить флаг android:exported.

▪️изменения в PendingIntents. Добавили флаги FLAGMUTABLE или FLAGIMMUTABLE, которй обязателен для каждого PendingIntents. Будьте внимательнее, если используете их.

▪️блокирование подозрительных нажатий. Это касается приложений, которые используют флаги SYSTEMALERTWINDOW или FLAGNOTTOUCHABLE. Стоит проверить своё приложение, если вы по какой-то причине эти флаги используете. Чуть больше тут.

▪️улучшили кодирование видео. Теперь HEVC будет основным кодеком, который обещает лучшее качество по сравнению с остальными форматами.

▪️поддержка изображений в формате AVIF. Обещают лучшее качество по сравнению с JPEG при тех же размерах файла.

▪️оптимизации foreground service. Теперь будут блокировать foreground сервисы, которые стартуют из background, если targetSDK написан под Android 12. Уже давно рекомендуют использовать WorkManager для подобных задач. Также увеличили время отображения оповещения для сервисов до 10 секунд, чтобы зря не беспокоить пользователя. Одно из самых важных обновлений для нас.

▪️новый интерфейс для добавления контента. Помимо вставки текста, пользователь может добавить, перетащить интересующий его контент из другого приложения при помощи drag-and-drop. Не уверен, что эта фича будет популярной, но почитать о ней можно тут.

▪️звуковой эффект с тактильной связью. Теперь приложения могут использовать вибро больше, давая фибдек на звучащее аудио.

▪️изменили вид уведомлений. Теперь уведомления не могут занимать всю область, так как это могло запутывать пользователей. Все уведомления будут иметь единый стиль. Тут можно посмотреть, как они будут выглядеть. Хорошее нововведение, Android станет ещё симпатичнее. 🤞🏻Кроме этого, теперь из приложений можно переходить только в Activity, нельзя использовать «батуты» (так их назвал Google) в виде broadcast или service.

Подробнее прочитать про все нововведения можно тут и тут. Как по мне, очень классный список улучшений. 🙃

Как вам обновления от Google?
​​Результаты фидбека о канале
#android_live

В одном из постов я просил дать фидбек о канале.
И сегодня я хочу сказать большое СПАСИБО всем, кто принял участие в опросе ✌🏻И немного расскажу вам о результатах.

В опросе приняло участие 80 человек. Это не большая выборка, однако и по ней можно сделать некоторые интересные выводы.

Возраст большинства участников от 21 до 35 лет.
Опыт большинства участников: от 1-3 лет, на втором месте 4-6 лет и 6-8 лет.
Было приятным сюрпризом, что меня читает большое количество взрослых и опытных разработчиков 🤟.

Сюрпризом не стал тот факт, что большинство, а именно 71 человек — это мужчины, а 9 — женщины. Что подтверждает вывод: в разработке большинство — это парни, но большое спасибо тем девушкам, которых меньше, но они приняли активное участие в опросе.

Сфера занятости — достаточно очевидно, Android-разработка – 73 человека. Помимо этого, есть люди, которые занимаются iOS, Flutter, Unity и руководят IT-командами.

Темы, которые нравятся — это обзоры статей, опыт практической разработки, библиотеки и советы дизайна. Чуть меньшему числу людей нравятся интервью с разработчиками.

Большинству из опрошенных нравятся картинки-превью — 70 людям. Это радует, так как мне они тоже нравятся 😁. И не хотелось их удалять из постов.
Реклама не раздражает ещё большее число людей — 78 человек. Рекламы и дальше не будет много, и она точно останется тематической.

Узнал, что большинству не очень нужен ещё один чат, который есть у канала — Уютный Android Live.
Я понимаю причину, так как чатов становится слишком много и выбирать интересные становится всё сложнее. Спешу образовать тех, кому он нравится – чат будет существовать и дальше, сохранив свой «уют».

Большинство из опрошенных не смотрит YouTube-канал. Пока он в начальном состоянии, но уже есть интересные идеи, анонсы которых вы обязательно увидите тут.

Часть опрошенных готова поддерживать канал материально, пока обдумываю наиболее удобную возможность для этого, анонс, также, будет сделан позже.
Однако, канал так и будет публиковать некоторые материалы бесплатно. 🤝

Ну и больше всего вы дали идей для контента. Не буду их перечислять, но многие из них я уже начал обдумывать, чтобы воплотить их. Огромное вам спасибо, и если у вас появятся ещё идеи, которые бы вы хотели чтобы я реализовал на канале — обязательно пишите мне.

И ещё раз спасибо всем за ответы и пищу для размышления. И я всегда открыт для обратной связи 😉.
​​Intent-фильтры в Android 12
#updates

Давайте детальнее вникать в те изменения, которые появились в Android 12. 👇🏻
Одно из них:

Activity Service или Broadcast Receiver с описанными intent-filters теперь должны явно указывать, следует ли их экспортировать или нет.

Если установить приложение с target SDK Android 12 и не описать явно флаг android:exported, то получите Exception. Но не стоит слепо добавлять true во все элементы, чтобы убрать это падение. Лучше задуматься, какие компоненты действительно должны быть видны другим приложениям.

Вот некоторые из тех, где с большей вероятностью должен быть true:
🔹Activity c android.intent.category.LAUNCHER;
🔹Activity c android.intent.category.VIEW;
🔹Activity c android.intent.category.SEND;
🔹Activity c android.media.browse.MediaBrowserService;

Но обязательно проследите за тем, чтобы компоненты, которые используются только вашим приложением были видны только ему. Это улучшит его безопасность, и радует, что теперь это обязательное требование.

Детальнее можно почитать в этой статье.
​​Миграция с LiveData на StateFlow
#livedata #flow #jetpack

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

🔹разработчики используют его повсюду, в том числе и в репозиториях, где его главная функциональность не нужна. Кроме того, репозиторий должен знать о минимальном количестве компонентов Android, а в лучшем случае вообще не знать;
🔹есть методы setValue() и postValue(), которые используются в зависимости от потока. И вам постоянно нужно помнить об этой разнице, когда вы делаете их вызов. В случае вызова setValue() не из UI-потока, вы получить Exception, а использование postValue() по всех случаях грозит проблемами. Отлично рассказали о разнице между этими методами тут.
🔹дополнительная зависимость в приложении. Меньшая из проблем, однако это лишняя библиотека, которую вам нужно затянуть в приложение.
🔹нет поддержки KMM.

Классной альтернативой является использование StateFlow. Он потокобезопасный, поддерживает KMM и не требует добавления новых зависимостей в проект.

Я уже начал мигрировать свой текущий проект на StateFlow и отмечу пару недостатков:

🔸нет привязки к жизненному циклу по умолчанию. Необходимо использовать методы типа lifecycleScope.launchWhenResumed() для обеспечания привязки.
🔸важно указывать значение при инициализации в отличии от LiveData. Решение для меня: если такого значения нет — указать null, а при подписке сделать фильтрацию на «не null». Просто один лишний оператор filterNotNull().

В остальном — шикарное решение, которое работает из коробки. Детальный гад по миграции и особенностям можно найти тут.

А вы уже переехали на Flow? Есть ли какие-то недостатки?
​​Ребят, а ведь сегодня 23 февраля — День защитника Отечества, ну и в этот день принято поздравлять всех мужчин и дарить им подарки.

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

Ну а в войну давайте играть только на Playstation, Xbox или ПК.

А давайте глянем, кто за что топит?
​​Annousing TheAndroidShow: Jetpack Compose
#compose #conference

Совсем недавно мы с вами смотрели за появлением alpha-версией Jetpack Compose, а между тем прошло 12 alpha-релизов и сегодня Google планирует анонсировать первую beta-версию!

Это шикарная новость, и даже организовано специальное мероприятие. Оно будет уже сегодня, 24 февраля в 20:00 по МСК. Ссылка с анонсом мероприятия тут. Надеемся, что на нём нам скажут дату релиза стабильной версии.

Кстати, есть классный канал, который посвящён полностью Jetpack Compose, рекомендую подписаться, чтобы не пропустить новостей, связанных с этим фреймворком. Кстати, с автором канала мы делали стрим, который может стать хорошим стартом в Compose 😉.
​​Android Scopes с Koin
#kotlin #koin #новичкам

Работа с жизненным циклом компонентов в Android может показаться достаточно сложной для новичков. Если дело касается работой с библиотеками для DI и Service Locator, то у многих появляется вопрос: как правильно управлять жизненным циклом компонентов?

Есть хорошая статья, которая расскажет о том, что такое Scope в Koin, и как правильно им управлять. Статья детальнее расскажет о встроенных в Koin скоупах, а также как сделать свой кастомный Scope.
Кстати, у Koin изменился дизайн сайта и, в целом, обновилась документация, а на носу выход свежих версий 3.0.1 и 2.3.0.
👍1
​​Выбор архитектуры для Jetpack Compose
#architecture #compose

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

Помочь в интеграции может эта статья. Автор сравнивает MPV, MVVM и MVI для использования с Jetpack Compose. Есть пример кода, где описывается логика проекта и то, как взаимодействуют слои. ✌🏻

Автор пришёл к выводу, что если в проекте есть MVVM и MVI, то интергрироваться с Jetpack Compose будет не так уж и сложно.
Мне кажется, что всё же идеальной архитектурой для Compose будет MVI.

Ссылка на исходный код проекта тут.
Тут неплохой канал с мемами для разработчиков подсказали — @java_memes.

Если хочется полистать ленту и почитать смешные мемы из IT, то вам сюда. Тут и про код, и про вакансии, и про текущие технологии, и про Яндекс со Сбером.

В общем, подписывайтесь — @java_memes.
​​Ещё больше про миграцию на Jetpack Compose
#architecture #compose

В предыдущей статье мы уже рассмотрели сравнение различных типов архитектур, а сегодня попалась ещё одна статья про использование Jetpack Compose в существующих проектах.

Автор в первой части рассказывает про Unidirectional Data Flow и про то, как применить его в проекте. По сути, это уже MVI паттерн для архитектуры, и можно посмотреть на пример его использования в простом проекте.

Вторая же часть уже связана непосредственно с имплментацией фичи. Это простой экран, который отображает список данных на экране. Автор показывает, как переходить от стандартного подхода в Compose-подход. Не уверен, что обязательно нужно делать столько слоёв, но в качестве примера подобный подход обязательно стоит рассмотреть.
​​Сравнение ArrayMap, SparceArray и HashMap
#theory

В Android SDK есть большой пласт коллекций, которые мы не используем: ArrayMap, SparseArray, ArraySet и т.д. Но все они дают определённые преимущества в сравнении с их более популярными «братьями».
И знание того, когда какую коллекцию использовать даёт преимущество при оптимизации приложения, а также при прохождении некоторых этапов собеседования.

В статье автор детально рассказывает, как работает ArrayMap: что будет, если добавить первый элемент, второй элемент и как разрешается коллизия.

Далее автор сравнивает эти три коллекции между собой, с точки зрения памяти и скорости доступа. Выводы:
▪️если у вас меньше 1000 элементов, то используйте ArrayMap, так как идёт выигрыш по памяти;
▪️если ключами является целое число, то используйте SparseArray, так как идёт ещё больший выигрыш по памяти;
▪️если значений больше 1000, то HashMap выигрывает по скорости;

Добавлю, что плюсом у HashMap является отсутствие привязки к Android SDK, что позволяет использовать её также и в KMM проектах.
Очень интересно изучать то, как работают коллекции изнутри и разбираться в привычных инструментах. 🔥
​​А сегодня у нас 8 марта — Международный женский день.

Поздравляю всех подписчиков женского пола с этим праздником, желаю тёплой весны, много цветов и любви.

Ну а парни — не забудьте поздравить ваших мам, жён и девушек с этим праздником, пусть улыбнутся.

А давайте тоже проголосуем, что лучше для подарка?
​​Практики работы с Coroutines
#coroutines

На сайте для разработчиков от Google появились практики работы с Coroutines. Давайте их рассмотрим.

🔹нельзя хардкодить Dispatchers. Особенно это касается работы с Coroutines во ViewModel. Google предлагает инжектить каждый диспетчер в отдельности и применять его в зависимости от контекста. Плюсом данного подхода является простота тестирования.
Из практики добавлю сюда передачу не конкретного элемента, а обёртки с 3 основными Dispatchers, которую можно переопределить для тестирования. На мой взгляд, такой подход удобнее.

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

🔹ViewModel должны быть ответственными за Coroutines. Довольно логичный паттерн: нельзя возвращать suspend-функцию во View, где запускать эту функцию и получать из неё какой-то результат. Правильнее будет использовать для этих целей Flow или LiveData.

🔹не делайте видимыми изменяемые типы из ViewModel, такие как MutableStateFlow или MutableLiveData. Это делается для того, чтобы избежать возможности отправки каких-то данных из View.

🔹слои бизнес-логики и данных должны возвращать или suspend-функции, или Flow. Плюсую за эту рекомендацию, потому что разработчики часто протаскивают LiveData во все слои приложения, где её фичи вообще не используются.

🔹избегайте GlobalScope. Это затрудняет тестирование и debug приложения. Если вам нужно «пережить» текущий экран, то стоит задуматься о scope, который будет управляться приложением или другим копонентом, живущим дольше, чем текущий экран.

🔹не забывайте про исключения. Обязательно стоит помнить о неуспешной работе suspend-функций и использовать для этого try-catch, хотя мне больше нравится CoroutineExceptionHandler.
​​Material Navigation Rail
#view #material

Возможно вы, как и я, пропустили выход свежей alpha-версии material-библиотеки. Туда включили фиксы, связанные с ProgressIndicator, а что нас больше интересует — так это новый компонент NavigationRail.

По сути, он повторяет функциональность BottomNavigationView, но располагается сбоку, а не снизу. Количество элементов при этом может быть от 3 до 7, а каждый компонент может включать в себя иконку, заголовок и значок-индикатор. Этот значок можно просто показать в виде точки, а можно добавить счётчик. Кроме этого, можно добавить header.

Как по мне, это хороший компонент, который раньше можно было реализовать при помощи RecyclerView.
Особенно компонент будет полезен приложениям, которые работают на планшетах. Чуть подробнее можно почитать о нём тут.
2025/08/29 11:24:20
Back to Top
HTML Embed Code: