We Love Android – Telegram
We Love Android
631 subscribers
259 photos
26 videos
4 files
630 links
Новости из мира Android-разработки
Download Telegram
Forwarded from Why Android? 🌚
Получил доступ к Remote Device Streaming от Google 🌚

Работает в Android Studio Iguana (Canary)
Чтобы включить надо в Help > Edit Custom Properties добавить

firebasetestlab.direct.access = true

Потом залогиниться в студии и выбрать Firebase проект, куда вам дали доступ.

И так:
🌶 работает довольно шустро. Доступные девайсы: Pixel 7, Pixel Fold, Pixel Tablet, Pixel Watch. Обещали Pixel 8, но похоже его быстро разобрали 🌚
🌶 на ремоут девайс приложение устанавливается как на обычный телефон
🌶 сами девайсы находятся недалеко от Вашингтона 😁
👍2🔥2
Forwarded from Mobile Native ️️
Lighten MVI architecture: Delegate responsibilities to new components

Интересная статья про то, как можно упростить и не перенагружать ViewModel, за счет делегирования логики другим компонентам(Processor, Reducer) в контексте MVI паттерна.

Код на GitHub → Contact book Android app

Читать (En)
👍2🔥2🤔2
Forwarded from Java: fill the gaps
IDEA: как не потерять важные места в коде

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

Раньше это делали так:
🔴 Ставили неактивный брейкпойнт в нужном месте. В принципе нормально, но иногда сложно вспомнить, что где находится
⭐️ Добавляли файл в favorites. Файл добавляется целиком, что не очень удобно

Затем в IDEA убрали favorites и добавили закладки. Супер удобно, ни одна важная строчка теперь не потеряется.

▫️ Курсор на нужной строке → F11 → появляется закладка
▫️ Правый щёлк по закладке → Rename bookmark… → ввести что-то осмысленное
▫️ Посмотреть закладки: View → Tool Windows → Bookmarks
👍3🔥3
Forwarded from Mobile Compose
#Article #Medium #Navigation

Best Practices for Compose Navigation in Multi-Module Project

Неплохая статья со списком лучших практик по организации навигации в многомодульном проекте с Compose.

Зеркало статьи 👉 тут
👍2🔥1
Forwarded from Android Live 🤖
Бродкасты в Runtime и Android 14
#android

Если вы вдруг решили поставить targetSDK до Android 14 (sdk 34), то обязательно перечитайте список изменений, на которые нужно обратить внимание.

Одним из неявных, но при этом вызывающих краш, изменений являются runtime-registered бродкасты.
Если раньше вы регистрировали их при помощи:
registerReceiver(receiver, IntentFilter())

то теперь необходимо регистрировать их так:
ContextCompat.registerReceiver(context, receiver, IntentFilter(), ContextCompat.RECEIVER_NOT_EXPORTED)

Можно передать RECEIVER_EXPORTED при необходимости.

Рекомендую поискать в своём проекте строку registerReceiver, потому что проект корректно собирается, никаких ошибок не появляется, но на свежем Android получите краш 😇.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🤔2🔥1
Forwarded from Mobile Native ️️
Миграция конфигурации сборки с Groovy на Kotlin

Еще один подробный гайд по миграции проекта с Groovy на Kotlin.

Читать (Ru)
👍2🔥1
Очень хорошо поднимают проблему редактирования текстов в мобильных интерфейсах. Прямо жиза, всегда плевался с этого. Если не хочется много читать, хотя бы посмотрите видео подхода, который они предлагают. Выглядит интересно.

#text #keyboard #mobile
👍2🔥2🤔1
Forwarded from Kotlin Adept Notes (Alex Panov)
Декларативный Bottom Sheet

На мой взгляд, самый неудачный компонент в Compose из Material 2 — это Bottom Sheet. Он долгое время крашился при изменении конфигурации, его кучу раз переписывали, но все-равно на сегодняшний день он содержит много проблем:
😀 Приходится пилить костыли для работы с WindowInsets
😀 Он не прилипает к низу экрана
😀 Производительность оставляет желать лучшего
😀 Скрытие Scrim нельзя кастомизировать

А самое худшее — это его императивный API, в котором мы вынуждены управлять его показом через suspend функции show/hide, а также приходится оборачивать контент экрана в ModalBottomSheetLayout. Это очень не удобно, когда нужно показать не статический контент, а полноценный экран с динамическим отображением данных и своей логикой.

😀Решить проблему можно с помощью кастомной декларативной обертки

Как это работает
Показываем Bottom Sheet, если ассоциированный с ним стейт ≠ null, иначе скрываем

Особенности реализации
Нужно уметь показывать предыдущий контент, пока bottom sheet скрывается, несмотря на то, что данных уже нет
Нужно правильно вызывать лямбду onDismiss и здесь можно допустить ошибку:
😀 Завязываться на confirmValueChange не вариант, так как теперь этот callback вызывается множество раз
😀 Отслеживание изменения sheetState.targetValue также может привести к проблемам, так как targetValue будет Hidden даже если вы не до конца скрыли Bottom Sheet

Проблема😀
На текущий момент если скрыть Bottom Sheet через изменение стейта, то его скрытие можно перехватить жестом и тогда останемся в неконсистентном состоянии. Решить проблему можно либо скрытием Bottom Sheet без анимации, либо не занулять стейт, пока он не будет полностью скрыт.

😀 Гораздо лучше дела обстоят в Material 3, там из коробки Bottom Sheet уже декларативный и в нем было решено большинство проблем, только вот далеко не все используют M3 в своих проектах и, чтобы использовать его реализацию, придется копировать к себе кучу исходного кода, что тоже не круто. Таким образом если вы еще не перешли на компоузовский Bottom Sheet, то лучше пока и не торопиться😉

А как вы боретесь с проблемами с Bottom Sheet в своем проекте?

#Compose
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔4😭3👍1🔥1
Forwarded from Why Android? 🌚
Tip of the day 🌚

Если надо что-то быстро посчитать не выходя из Android Studio, то по double shift можно запустить встроенный калькулятор
🤯13🔥3👍2🤔1
Forwarded from Android Guards
Умение обходить фильтры - очень важный навык. Обычно он складывается из двух компонентов: развитого аналитического мышления и знания трюков. Сегодня будут трюки. Представим себе такой синтетический фильтр:
val input = "http://evil.com"

val filter = """^(https?)://.*@?evil\..+""".toRegex()

if (filter.matches(input)) {
throw MalformedURLException("Banned URL!")
}

val okhttp = OkHttpClient()
val req = Request.Builder().url(URL(input)).build()

Есть мысли как его обойти? Подумайте 30 секунд.

Один из способов - модифицировать input любым из этих способов:
- url:http://evil.com
- http://evil.com (первый символ - пробел)

Но проверка по черному списку встречается все реже. Кажется, что разработчики начинают что-то подозревать 😰
#aht
👍4🔥2😱1
Forwarded from Android Good Reads (Egor Tolstoy)
Как работают текстовые кодировки

Записали топовый выпуск Подлодки про разные неочевидные аспекты устройства текстовых кодировок и работы с ними. Больше всего, конечно, про Unicode. Если хотите узнать, почему в любом приложении, работающем с текстом, есть баги – обязательно слушайте!

По мотивам подкаста Никита Прокопов написал еще и шикарную статью, в которой подбил основные тезисы.
👍3🔥1
Forwarded from Mobile Developer (Алексей Гладков)
KMP Coroutines to Swift Async/Await [EN]
https://akjaw.com/async-await-coroutines-in-swift-using-kmp-nativecoroutines/

Невероятно огромная статья по тому как использовать корутины из кмп через async/await механизм в Swift. Очень полезно для SwiftUI

👉 Настройка ViewModel
👉 Что такое @NativeCoroutines
👉 Работа с Flow
👉 Обработка ошибок и отмен
👉 и многое другое...

Приятного чтения
Статья must read 🔥
👍2🔥2
😁15
Один аккаунт на два приложения

Авторизовался в приложении А, а потом открыл приложение Б

А там окошко "Хотите войти под тем же аккаунтом?"

Как?

Ответ: через посредника == системный сервис == AccountManager

Что произошло под капотом:

1. Приложение А получило ваш логин и пароль

2, Приложение А проверило через бекенд, что вы существуете

3, Приложение А обратилось к системному AccoutManager, создало в нем Account и положило в него ваш логин и пароль

4. Приложение Б в момент запуска тоже обратилось к AccountManager, вязало Account и увидела ваш логин и пароль

Готово, приложение Б может авторизовать вас под тем же аккаунтом, не заставляя вспоминать пароль


Схема начинает выглядеть более безопасно, если учесть два факта:

• Account можно передавать только между приложениями, имеющими одну подпись

• прихранивать логин и пароль в сыром виде не стоит. вместо этого можно передавать обезличенный токен, зашифрованный на бекенде


Почему вам это надо:

• пользователю не нужно вспоминать пароль == увеличивается шанс, что он авторизуется

• компании не надо тратить деньги на СМС с кодом авторизации
👍3🔥2🤔1
Forwarded from Android Broadcast (Кирилл Розов)
Автор статьи (15 мин) предлагает свое видение хорошей архитектуры Android приложения с набором правил что надо и Не надо делать

#architecture
3🤔3👍2
Forwarded from По-явански
Раздельная компиляция, min, compile, target

В целом Java-технологии привычные к раздельной компиляции. Серверные приложения компилируются с Java Class Library, которая подкладывается в compile classpath при сборке, а запускаются с другим экземпляром JCL, которая лежит на сервере.

Однако, эта раздельность почти не чувствуется. Она незримо присутствует и заключается в том, что в итоговом jar у нас не лежит весь java.lang, java.util и что мы там ещё любим. Мы запускаем приложение с той же версией JDK, с которой собирали, и всё просто работает.

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

В desktop-приложениях (кто-то их ещё пишет?) всё ещё проще: зачастую JVM приносят с собой, и раздельной компиляции как не бывало.

В Android же, как известно, зоопарк: на конечных устройствах много разных версий. И вот тут система сборки спроектирована очень удачно:
• compile SDK — последняя версия, известная разработчику приложения на момент сборки. Она подкладывается в compile classpath, за счёт чего разработчик видит все новые фичи платформы;
• min SDK — минимальная поддерживаемая версия. Старой платформе, которую разработчик не хочет поддерживать, позволяет отклонять установку приложений. Инструментарию позволяет подсказать программисту, что те или иные declarations недоступны в min и могут отсутствовать в runtime classpath, поэтому нужно обернуть их использование в if;
• target SDK — версия, на поведение которой рассчитывает приложение. Позволяет более новой версии платформы сохранить поведение старой в старом приложении.

Таким образом, в быстро меняющемся мире Android-приложение компилируется для свежей версии платформы (compile SDK), ифами поддерживает более старые версии (вплоть до min SDK), а платформа, если она новее, чем ожидаемая (target SDK), сохраняет старое совместимое поведение (тоже ифами).

Это прекрасно. Это шедевр.

Для сравнения, ситуация в мире плагинов для IntelliJ: выбираешь одну версию, которая и будет твоим compile и min. Хочешь поддержать постарше — опускаешь версию, перестаёшь видеть новые declarations. Если в новых версиях что-то deprecated — ты об этом узнаешь на этапе валидации плагина, где-то после компиляции и упаковки.

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

Зависишь от других плагинов? Вообще страдай. Там может быть установлена любая версия. Например, если зависишь от Android-плагина для IDE, то при компиляции видишь версию, которой полгода, а в бетах Android Studio уже много раз переименовали классы, поменяли на интерфейсы, переместили в другой пакет. (И сделали это в стенах той же компании, где придумали min, compile, target.) Удачи!
😁3👍2🔥1
Forwarded from Dev Easy Notes (Nikita)
Итак, ребята, взгляните на статью. Ничего не смущает? А вот эта? Дело в не в оформлении или стиле повествования дело в самой теме. Что первая статья, что вторая по своей сути просто пересказ книги Мартина с щепоткой заезженных истин вроде: важна золотая середина, выбирайте что лучше для вашего приложения отталкивайтесь от бизнеса требований и бла, бла, бла.

Первую статью закинули в наш Android чатик компании, с припиской поделится мнениями. Меня это не на шутку удивило, на самом деле разозлило. За последние лет 5, никто ничего концептуально нового для многомодульной архитектуры не придумал. Все эти статьи буквально пересказ предшественников и в 2023 году на серьезных щах обсуждать эти подходы это блять смешно. Вот серьезно идите посмотрите доклад Неклюдова, а потом прочитав эти статьи ответьте на вопрос, много нового они привнесли?

Вот знаете же миф о том, чтобы разработчику оставаться на одном месте ему нужно постоянно учиться. Я вот уже давно не читаю статьи по мобильной разработке и все жду того момента, когда ничего не буду понимать. За последние 5 лет самым значимым изменением было внедрение compose. Но это всего лишь один UI слой, не говоря уже о том, что большие проекты только-только начинают на него переезжать и то с большим скрипом.

Архитектуры в мобилке до жути простые и они везде одинаковые в 90% случаев. Оставшиеся 10% это какие-нибудь рибс, и то по сути те же яйца, только в профиль. Я даже не уверен, что имеет смысл говорить об архитектуре модулей когда речь идет о мобильном приложение. У бэкендеров другое дело, у них реально миллион способов связать сервисы друг с другом и там имеет место обсуждение архитектур. Потому как проеб в архитектуре у бэкендеров это реальная потеря бабок.

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

Смотрите, первое, что нужно спросить на ней про устройство команды и планы компании. Если у нас мелкая команда и проект это проверка гипотезы, делаем одномодульное приложение и вообще не паримся. Однако на собесах почти всегда это будет приложение, где у нас ебанутся какие большие планы и нам нужно выбрать архитектуру, которая бы позволила работать над приложением большой командой. В этом случае вы, разумеется должны сказать, что тут явно нужна многомодульная архитектура. Еще можно про закон Конвея рассказать.

Затем вы собираете требования по фичам проекта и тупо отдельные фичи располагаете в разных модулях. Делаете модуль app, показываете что там есть di, затем добавим модуль навигации, ну а че бы и нет. Дальше у вас только два варианта как располагать модули. Либо всю бизнес логику делать внутри feature и если нужно шарить делаете api модуль с интерфейсами, либо делаете отдельные domain модули в которых уже будут всякие repository и interactor.

Дальше желательно сказать что проксирующие интеракторы это херня из под коня и если интервьюер адекватный, ему это понравится. Дальше вам лишь нужно выбрать уже готовую архитектору для Presentation слоя: MVVM или MVI. MVP уже никто не воспринимает всерьез. Расклад такой: с MVVM проще онбординг новых сотрудников, и она лучше по памяти когда дохера событий на экране, но она хуже когда много асинхронщины. MVI сложнее в онбординге, и создается новый State на любой чих, зато один единый State и вы забываете что такое Race Condition. Бум, все, идите к начальству и просите зарплату архитектора.
👍6🤔3🔥1