🤖 MediaPipe LLM Inference больше не развивают: Google советует переходить на LiteRT-LM
Google сменила курс по on-device LLM одной плашкой в документации Google AI Edge: LLM Inference API из MediaPipe для Android, iOS и веба теперь только поддерживают, а новые возможности и оптимизации делают в LiteRT-LM. Когда это произошло, Google не пишет, но затишье видно и по релизам — последняя версия
LiteRT-LM — рантайм Google для языковых моделей поверх LiteRT. У него свой Kotlin API для Android и JVM с ускорением на GPU и NPU, мультимодальностью и вызовом инструментов. Модели нужны в формате
Для GPU в манифест нужно добавить
🔗 MediaPipe LLM Inference · LiteRT-LM для Android · dev.to
#Android #AndroidDev #AI #LiteRT
Google сменила курс по on-device LLM одной плашкой в документации Google AI Edge: LLM Inference API из MediaPipe для Android, iOS и веба теперь только поддерживают, а новые возможности и оптимизации делают в LiteRT-LM. Когда это произошло, Google не пишет, но затишье видно и по релизам — последняя версия
tasks-genai вышла на Google Maven ещё в конце апреля. Если вы через MediaPipe встроили в приложение языковую модель, которая работает прямо на телефоне, она продолжит работать, но всё новое теперь появляется только в LiteRT-LM, так что переезд стоит спланировать заранее.LiteRT-LM — рантайм Google для языковых моделей поверх LiteRT. У него свой Kotlin API для Android и JVM с ускорением на GPU и NPU, мультимодальностью и вызовом инструментов. Модели нужны в формате
.litertlm, готовые лежат в LiteRT Community на Hugging Face. Актуальная версия — litertlm-android:0.18.0, ещё до 1.0. Базовый сценарий из документации:val engine = Engine(EngineConfig(modelPath = modelPath, backend = Backend.GPU()))
engine.initialize() // до ~10 секунд, не на главном потоке
engine.createConversation().use { conversation ->
conversation.sendMessageAsync("Привет!").collect { print(it) }
}
Для GPU в манифест нужно добавить
uses-native-library для libOpenCL.so и libvndksupport.so с required="false".⚠️ В AAR LiteRT-LM 0.18.0 нативные библиотеки есть только для arm64-v8a и x86_64. На 32-битных ARM-устройствах загрузка упадёт сUnsatisfiedLinkError, поэтому проверяйтеBuild.SUPPORTED_ABISзаранее — на это наткнулся Charles Hartmann.
🔗 MediaPipe LLM Inference · LiteRT-LM для Android · dev.to
#Android #AndroidDev #AI #LiteRT
❤2👍2
В 2025 году Google объявил deprecated всю библиотеку security-crypto вместе с EncryptedSharedPreferences и предложил работать с Android Keystore напрямую. Готовой замены «подключил и забыл» не было. Теперь она есть: в DataStore 1.3 появился артефакт
datastore-tink, а 12 октября вышел 1.3.0-rc01, то есть API уже стабилен.Шифрование подключается обёрткой над вашим сериализатором:
AeadSerializer шифрует данные через Tink (AES-256-GCM), а ключ защищён Android Keystore.// keysetHandle создаётся через AndroidKeysetManager
val aeadSerializer = AeadSerializer(
aead = keysetHandle.getPrimitive(
RegistryConfiguration.get(), Aead::class.java
),
wrappedSerializer = SettingsSerializer,
// уникальное имя защищает от подмены шифротекста
associatedData = "settings.json".encodeToByteArray(),
)
val dataStore = dataStore(
fileName = "settings.json",
serializer = aeadSerializer,
scope = scope,
)
Работает на Android и JVM. Ошибки расшифровки приходят как
CorruptionException, так что их ловит обычный CorruptionHandler. Заодно в 1.3 появился DataStore.Builder, и Google советует переходить на него с DataStoreFactory.🔗 Release notes DataStore · Разбор на ProAndroidDev
#Android #AndroidDev #DataStore #Security
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥62
🚀 Grab включил R8 на 10 млн строк кода и избавился от всплесков ANR после релизов
«Каждый еженедельный релиз — всплеск ANR», — так описывают жизнь команды Grab, суперприложения из Юго-Восточной Азии с 10-летней кодовой базой. Холодный старт тормозило чтение множества DEX-файлов, а Cloud Profiles из Google Play не покрывали их критичные пути вроде сборки графа Dagger.
Сначала команда перешла на
Итог: ANR меньше на 32%, холодный старт быстрее на 35%. Недавно писал, что Google взялся за R8 всерьёз, — вот как это выглядит на большом проекте.
🔗 Кейс Grab
#Android #AndroidDev #R8 #Performance
«Каждый еженедельный релиз — всплеск ANR», — так описывают жизнь команды Grab, суперприложения из Юго-Восточной Азии с 10-летней кодовой базой. Холодный старт тормозило чтение множества DEX-файлов, а Cloud Profiles из Google Play не покрывали их критичные пути вроде сборки графа Dagger.
Сначала команда перешла на
proguard-android-optimize.txt и добавила Baseline и Startup Profiles, через девять месяцев — на R8 full mode. Вместо широких исключений нашли конкретные классы, к которым обращаются через рефлексию и динамические прокси, и написали для них точечные keep-правила. Оценки оптимизации R8 теперь отслеживают в CI, а новые keep-правила планируют пропускать только с обоснованием.Итог: ANR меньше на 32%, холодный старт быстрее на 35%. Недавно писал, что Google взялся за R8 всерьёз, — вот как это выглядит на большом проекте.
🔗 Кейс Grab
#Android #AndroidDev #R8 #Performance
🔥26👍11
Чтобы запустить Android-приложение на Mac, обычно поднимают эмулятор — целый Android в виртуальной машине. Автор Mac.apk пошёл путём Wine: его программа сама изображает Android поверх macOS. 19 октября код открыли под AGPL-3.0.
При первом запуске DEX переводится в Java-байткод и работает на встроенной OpenJDK, 64-битный ARM-код выполняется на чипе Apple как есть, а графика идёт через ANGLE и MoltenVK в Metal. Каждое приложение — отдельное окно с иконкой в Dock.
Разработчикам важно: на Mac.apk ваше приложение запускается без настоящих Google Play Services: Play Billing и Play Integrity недоступны, а рекламный SDK Google получает пустой ответ. Если не хотите видеть там своё приложение, автор по запросу внесёт его в список блокировки.
⚠️ Это альфа-версия: нужны Apple Silicon и macOS 26.4+, часть приложений пока не запускается.
🔗 GitHub · Как это устроено · Для разработчиков
#Android #AndroidDev #macOS #OpenSource
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥32👍7
Агент обновляет библиотеку с ломающими изменениями, а нового API нет в его обучающих данных, и по сотням файлов сыплются ошибки компиляции. С разбора таких ситуаций начинается новый раздел AI tools на developer.android.com: агент — это LLM плюс обвязка с инструкциями, инструментами, навыками и циклом выполнения.
Главный практический совет: пишите в AGENTS.md конкретные команды и пути, а не пожелания. Не «убедись, что проект собирается», а
./gradlew assembleDebug; не «бери свежие версии», а «версии из gradle/libs.versions.toml, новые зависимости — только после вопроса». Навыки устаревают, поэтому свежие факты агенту лучше давать через поиск по документации в Android CLI.В квикстарте инструменты подобраны под опыт: новичкам — Google AI Studio, своему агенту вроде Claude Code — Android CLI и skills, для продакшена — Android Studio.
🔗 Как работают агенты · Квикстарт
#Android #AndroidDev #AI #AIAgents
Please open Telegram to view this post
VIEW IN TELEGRAM
👍28❤5
🤖 Виджеты на Android 17: слишком тяжёлые картинки теперь роняют приложение
Приложение обновляет виджет с парой крупных фото и падает с
Лимит —
👉 Размер экрана берите из
👉 Уменьшайте картинки до размеров виджета, а для непрозрачных используйте
👉 В Glance декодируйте Bitmap один раз в
URI-картинки в лимит не входят, но лаунчер декодирует их в полном разрешении, так что класть в
🔗 Изменения поведения Android 17 · Виджеты на Glance
#Android #AndroidDev #Android17 #AppWidgets
Приложение обновляет виджет с парой крупных фото и падает с
IllegalArgumentException: RemoteViews for widget update exceeds maximum bitmap memory usage. Так Android 17 ведёт себя с приложениями на targetSdk 37: если картинки в RemoteViews не влезают в лимит, система отклоняет обновление и бросает исключение. На targetSdk 36 и ниже это пока только предупреждение в логе. Google переписал описание этого изменения и добавил, как считается лимит и как в него уложиться.Лимит —
6 * width * height байт, то есть полтора полноэкранных буфера ARGB_8888. Считаются картинки для всех ориентаций и размеров виджета сразу, поэтому responsive-виджет легко съедает бюджет копиями одного и того же Bitmap.👉 Размер экрана берите из
WindowManager.currentWindowMetrics, а не из displayMetrics: на складных устройствах тот может вернуть размер неактивного дисплея.👉 Уменьшайте картинки до размеров виджета, а для непрозрачных используйте
RGB_565 — это вдвое меньше памяти.👉 В Glance декодируйте Bitmap один раз в
provideGlance до provideContent, иначе для каждого размера создаётся своя копия.URI-картинки в лимит не входят, но лаунчер декодирует их в полном разрешении, так что класть в
cacheDir тоже стоит уменьшенную версию.🔗 Изменения поведения Android 17 · Виджеты на Glance
#Android #AndroidDev #Android17 #AppWidgets
👍20❤4
🚀 Предусловия UI-тестов через API — не всегда быстрее: замеры на 400+ Android-тестах
Почти каждый UI-тест в Android-приложении финансового сервиса начинался одинаково: шесть экранов логина и около 26 секунд, хотя логин эти тесты не проверяли. Команда проверила на Хабре известный совет «готовьте предусловия через API, а не через UI» на трёх кейсах в сьюте на Kaspresso.
Для логина совет сработал: вход через auth-слой приложения занял ~7 секунд вместо ~26, а общее время 418 тестов сократилось на 27%. А переключение тумблера через PATCH оказалось на 29% медленнее трёх тапов. Тест сам грузил большой список продуктов, который приложение потом загружало ещё раз.
Вывод авторов: выигрыш даёт не API сам по себе, а то, что из теста уходит длинная UI-цепочка, которая не лежит на пути к проверяемому экрану.
🔗 Статья на Хабре
#Android #AndroidDev #Testing #Kaspresso
Почти каждый UI-тест в Android-приложении финансового сервиса начинался одинаково: шесть экранов логина и около 26 секунд, хотя логин эти тесты не проверяли. Команда проверила на Хабре известный совет «готовьте предусловия через API, а не через UI» на трёх кейсах в сьюте на Kaspresso.
Для логина совет сработал: вход через auth-слой приложения занял ~7 секунд вместо ~26, а общее время 418 тестов сократилось на 27%. А переключение тумблера через PATCH оказалось на 29% медленнее трёх тапов. Тест сам грузил большой список продуктов, который приложение потом загружало ещё раз.
Вывод авторов: выигрыш даёт не API сам по себе, а то, что из теста уходит длинная UI-цепочка, которая не лежит на пути к проверяемому экрану.
🔗 Статья на Хабре
#Android #AndroidDev #Testing #Kaspresso
❤7👍3
Поздно вечером 17 октября Mozilla получила сообщение: закрытые ключи восьми промежуточных сертификатов удостоверяющего центра eMudhra скомпрометированы. С ними можно выпустить поддельный HTTPS-сертификат для чужого сайта, и клиент, который доверяет этим корням, его примет. Firefox заблокировал сертификаты меньше чем за три часа, а 20 октября Mozilla убрала корень из своего хранилища NSS.
Приложения на OkHttp уязвимы, пока не обновится список доверенных корней платформы, а на Android и JVM это может занять очень долго. Поэтому Jesse Wilson 20 октября выложил обходной путь, а 22 октября вышли OkHttp 5.5.1 и 4.12.1, которые сами блокируют эти 8 сертификатов. Достаточно поднять версию.
Если обновиться сразу нельзя, подключите ForbiddenCertificatesHostnameVerifier из гиста, он работает со всеми поддерживаемыми версиями OkHttp:
val safeClient = client.newBuilder()
.hostnameVerifier(ForbiddenCertificatesHostnameVerifier())
.build()
⚠️ Первая версия обхода была на Interceptor, но он получает сертификаты слишком поздно, когда секреты уже ушли атакующему. Если вы скопировали её 20 октября, замените на HostnameVerifier. На устройствах с Google Play Services Google уже раздал автоматическое обновление, под угрозой прежде всего JVM и AOSP-устройства.
🔗 Jesse Wilson · Mozilla · Changelog 5.5.1 · 4.12.1
#Android #AndroidDev #OkHttp #Security
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥34❤7👍4
Один и тот же пуш мгновенно приходит на Pixel — и не приходит вообще на Redmi. Разработчик часами копается в FCM, а виноват не он: Xiaomi, Redmi, Poco, Oppo, Realme, Vivo, iQOO и OnePlus добавляют поверх Android свой агрессивный менеджер батареи, который останавливает приложения в фоне. А остановленное приложение пушей не получает.
Что делают эти прошивки
• Автозапуск выключен по умолчанию (MIUI/HyperOS, ColorOS) — пуш, которому нужен ваш код, не может его запустить.
• Смахивание из недавних = Force stop. Android не доставляет сообщения force-stopped приложению, пока его не откроют.
• Профили экономии батареи ограничивают фон, иногда через несколько дней без открытия приложения.
• Уведомления на экране блокировки и всплывающие выключены — пуш пришёл, но пользователь его не видит.
Что можно сделать в приложении
• Важное — через notification messages, а не data-only: их показывает система без запуска вашего кода.
• High priority — только для того, что пользователь ждёт (подтверждение входа, статус заказа).
• Разные каналы для логинов и промо, чтобы отключение одного не глушило другой.
• Просите настройку один раз и в нужный момент, а не всем в первый день.
• Pull в дополнение к push: при открытии приложения подтягивайте пропущенное — тогда недошедший пуш лишь опоздал, а не потерялся.
Для экрана настроек есть стандартные интенты, а для автозапуска у вендоров публичного API нет:
Как проверить, что дело в прошивке: отправьте одно и то же уведомление на Pixel/Samsung и на Xiaomi, смахнув приложение на обоих. Пришло на первом, но не на втором — это battery saver, и одними изменениями на сервере это не исправить.
🔗 Why push notifications go missing on Xiaomi, Oppo, Vivo and Realme
#Android #AndroidDev #FCM #Push #Xiaomi
Что делают эти прошивки
• Автозапуск выключен по умолчанию (MIUI/HyperOS, ColorOS) — пуш, которому нужен ваш код, не может его запустить.
• Смахивание из недавних = Force stop. Android не доставляет сообщения force-stopped приложению, пока его не откроют.
• Профили экономии батареи ограничивают фон, иногда через несколько дней без открытия приложения.
• Уведомления на экране блокировки и всплывающие выключены — пуш пришёл, но пользователь его не видит.
Что можно сделать в приложении
• Важное — через notification messages, а не data-only: их показывает система без запуска вашего кода.
• High priority — только для того, что пользователь ждёт (подтверждение входа, статус заказа).
• Разные каналы для логинов и промо, чтобы отключение одного не глушило другой.
• Просите настройку один раз и в нужный момент, а не всем в первый день.
• Pull в дополнение к push: при открытии приложения подтягивайте пропущенное — тогда недошедший пуш лишь опоздал, а не потерялся.
Для экрана настроек есть стандартные интенты, а для автозапуска у вендоров публичного API нет:
// Системный список исключений из оптимизации батареи
startActivity(Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS))
// Страница настроек приложения: там на большинстве телефонов Autostart и батарея
startActivity(Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.fromParts("package", packageName, null)))
⚠️ Google Play разрешает прямой запрос исключения (REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) лишь в немногих случаях — большинству приложений стоит вести пользователя на экран настроек.Как проверить, что дело в прошивке: отправьте одно и то же уведомление на Pixel/Samsung и на Xiaomi, смахнув приложение на обоих. Пришло на первом, но не на втором — это battery saver, и одними изменениями на сервере это не исправить.
⚠️ Названия пунктов меню меняются между версиями прошивок — актуальные инструкции по брендам собраны на dontkillmyapp.com.
🔗 Why push notifications go missing on Xiaomi, Oppo, Vivo and Realme
#Android #AndroidDev #FCM #Push #Xiaomi
👍34❤2
🚀 Sentry Android SDK стал на 20–30% быстрее при старте: что поменяли
Приёмы, которые пригодятся и в вашем коде:
👉 Настройки из манифеста — в байткод при сборке: SDK больше не парсит манифест, одно это дало 6,5%.
👉 Свой парсер DSN вместо
👉 Общие пулы вместо разовых потоков: в ART каждый поток резервирует 1 МБ под стек.
Нужны SDK от 8.54.0 и Sentry Android Gradle Plugin от 6.20.0.
🔗 Sentry Blog
#Android #AndroidDev #Performance #Sentry
SentryAndroid.init стоит на критическом пути запуска каждого приложения с Sentry, а таких стартов, по подсчётам компании, около 4,5 млрд в день. За квартал команда сделала больше 40 изменений и сократила инициализацию на 20–30% между версиями 8.43.0 и 8.54.0. Узкие места искали по трейсам Perfetto, в том числе с LLM, а каждый фикс проверяли Macrobenchmark.Приёмы, которые пригодятся и в вашем коде:
👉 Настройки из манифеста — в байткод при сборке: SDK больше не парсит манифест, одно это дало 6,5%.
👉 Свой парсер DSN вместо
java.net.URI: было до 6 мс, стало около 1 мкс.👉 Общие пулы вместо разовых потоков: в ART каждый поток резервирует 1 МБ под стек.
Нужны SDK от 8.54.0 и Sentry Android Gradle Plugin от 6.20.0.
⚠️ Цифры сняты на синтетическом демо-приложении, в реальных проектах эффект может отличаться.
🔗 Sentry Blog
#Android #AndroidDev #Performance #Sentry
🔥17