We Love Android – Telegram
We Love Android
631 subscribers
259 photos
26 videos
4 files
630 links
Новости из мира Android-разработки
Download Telegram
Forwarded from Mobile Developer (Алексей Гладков)
Внутренности ANR [EN]
https://blog.p-y.wtf/anr-internals-touch-dispatching-through-the-view-hierarchy

Как же я люблю такие статьи, где не просто поверхностно прошлись, а прям объяснили как это работает

👉 Как устроен механизм touch dispatch
👉 Сравнение механизмов View и Compose
👉 Как это все связано с ANR
👍2🔥2🤔1
Forwarded from Java: fill the gaps
Сегодня релиз Java 21🥳

Главные фичи новой версии:

🔸 Виртуальные потоки

В чём суть: для многих задач производительность ограничивается количеством потоков в ОС. Чтобы обойти это ограничение и использовать потоки на максимум, придумали множество способов — асинхронные библиотеки, реактивное программирование и тд. Вариант рабочий, но код усложняется.

Виртуальные потоки позволяют писать простой код и не упираться в ограничения ОС.

Ближайший аналог виртуальных потоков — горутины в Go. Собственно, горутины — основная причина, почему многие сервисы написаны на Go.

Более дальний аналог — корутины в Kotlin. Они имитируют виртуальные потоки на уровне библиотеки и несут большие накладные расходы. В java виртуальные потоки реализованы на уровне JVM, поэтому их производительность гораздо выше.

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

🔸 Pattern matching

В этих постах (один, два) я подробно расписала, зачем нужен pattern matching в целом, и как он реализован в java. Вкратце: нужен не всем, реализация в джаве так себе

🔸 Sequenced collections

Новые методы в коллекциях: getFirst(), getLast(), reversed() и другие. Подробный пост тут

Интересные preview фичи:

🔹 String templates — интерполяция строк, возможность писать

String str = "Hello, ${name}!";

Подробнее в этом посте

🔹 Scoped Values — аналог ThreadLocal c ограниченной областью действия
🔹 Structured Concurrency — способ организации подзадач в многопоточной среде

Остальные фичи очень специфичные и вряд ли пригодятся большинству разработчиков:

▫️ Generational ZGC — в сборщик добавили поколения, как следует из названия. Молодые объекты будут собираться чаще, и сборщик будет работать эффективнее
▫️ Record Patterns — records можно использовать внутри case
▫️ Foreign Function & Memory API (Third Preview) — методы для работы с нативным кодом и управлению памятью за пределами JVM. Это нужно для приложений, которые хотят сами управлять размещением объектов в памяти и не зависеть от сборщика мусора.
▫️ Unnamed Patterns and Variables (Preview) — можно не указывать имя переменной, если оно не нужно. Вместо него ставить _

Например, в case:
case Point(int x, _) → …

Или при ловле исключения:
catch (IllegalStateException _)

Было бы удобно сделать такое для лямбд, но для этого есть отдельный JEP, который сделают чёрт знает когда

▫️ Deprecate the Windows 32-bit x86 Port for Removal — перестать работать с Windows 32-bit x86, в будущем удалить
▫️ Prepare to Disallow the Dynamic Loading of Agents

Агент — компонент, который изменяет классы при загрузке или меняет уже загруженные классы в JVM. Используется для мониторинга, профайлинга и других служебных целей

▫️ Key Encapsulation Mechanism API — методы для защиты ключей симметричного шифрования
▫️ Unnamed Classes and Instance Main Methods (Preview)

Видимо чтобы короче писать Hello World:
class HelloWorld {
void main() {
System.out.println("Hello, World!");
}
}

Вот такой релиз. Конечно, самая ожидаемая фича — это виртуальные потоки. Если планируете в ближайшее время внедрять их, отпишитесь по впечатлениям, мне очень интересно😊
🤯3👍2😱1
This media is not supported in your browser
VIEW IN TELEGRAM
Tiling — это реализация пагинации на основе состояния, которая представляет выгружаемый набор данных в виде простого списка. Он обеспечивает постоянный доступ к элементам по индексам в режиме реального времени и возможность самоанализа элементов, просматриваемых по страницам.

Tiller доступен в mavenCentral:

implementation com.tunjid.tiler:tiler:version

Читать статью

#гайд
👍2🤔2👎1🔥1
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