Telegram Web
​​Chrome Inspect
#android

Совсем недавно узнал о таком инструменте Chrome как chrome://inspect. Возможно, вы, как и я, услышите о нём впервые.

Он больше подходит, если вы пишите веб-приложения, однако, есть кейсы, когда он нужен и нам – Android-разработчикам: например, при отображении контента с WebView и его дебага.

💡Пользоваться им очень просто:

1️⃣ Включаем режим разработчика на смартфоне (кажется, что вы все это сделали).
2️⃣ Ввводим в строку браузера chrome://inspect и подключаемся к телефону.
3️⃣ В целом, на этом всё: мы можем анализировать код, который приходит в нашу WebView, ставить callbacks и анализировать логи.

Радует тот факт, что с нас не требуется установки никаких дополнительных зависимостей, ведь использовать его мы будем не очень часто.
👍21💩3
​​Android Manifest placeholders
#android

Уверен, что большинство из вас слышали про то, что такое buildConfigField.
Если нет, то по сути — это возможность объявить переменную внутри build.gradle и её дальнейшее использование внутри приложения.

Правда, вы не можете ссылаться на эту переменную внутри AndroidManifest. Самый типичный кейс — добавление идентификатора приложения для всяких сервисов, типа HMS или GMS. Но тогда на помощь приходит менее распространённый, но весьма крутой инструмент manifestPlaceholders.

💡Использовать его довольно просто: объявляем переменную через manifestPlaceholders.variable = "testVariable", а дальше получаем ссылку на неё в AndroidManifest при помощи:
<meta-data
android:name="variable_name"
android:value="${testVariable}"/>


Таким образом, мы можем настроить нужное нам поведение хоть на этапе сборки приложения, хоть для отдельного flavor. Берите на заметку. 😉
👍193🔥2💩1
​​Релиз Android 13
#android

Как и в последней паре релизов, ближе к концу лета у нас появляется новая, стабильная версия Android, в этот раз — 13.
Скоро ещё больше смартфонов получат новое обновление, а нам, разработчикам, надо обновить targetSdk до 33 версии.

🤓 Давайте кратко пройдёмся по тем пунктам, которые важно проверить у себя перед релизом:

🍦Read Media Permission — теперь при использовании android.permission.READEXTERNALSTORAGE вам необходимо описать, к каким типам файлов вы хотите получить доступ. Например, если вам нужны только изображения, то необходимо указать: android.permission.READMEDIAIMAGES.
Но не спешите удалять старый READEXTERNALSTORAGE: ему можно указать android:maxSdkVersion="32", сохранив корректную работу на уже старых версиях Android.

🍦Android 13 Photo Picker — также, для получения изображений и других медиа-объектов, можно воспользоваться PhotoPicker, который вскоре будет работать на Android 11 и выше. Это на случай, если вам не нужно постоянно иметь доступ к галерее пользователя. Довольно удобно.

🍦Notifications runtime permission — теперь не получится показать уведомления без разрешения пользователя. Для начала добавим:
<uses-permission android:name="android.permission.POSTNOTIFICATIONS" /> в манифесте, а после нужно запросить разрешение у пользователя по аналогии с обычным запросом разрешений.

🍦* Google Play Advertising ID* — проверьте, используете ли вы рекламный идентификатор в своём приложении. Кстати, даже если ваше приложение напрямую его не использует, проверьте библиотеки для аналитики, часто именно они запрашивают этот идентификатор.
Если нашли — не забудьте заполнить форму в Google Play, а также добавить разрешение в манифест:
<uses-permission android:name="com.google.android.gms.permission.AD
ID"/>.

🍦и ещё парочку дополнений, таких как корректная окраска сайтов в WebView, оптимизаций батареи, Intent Filter Restrictions и т.д. Классная статья с подробным описанием тут.

В целом, я уже в ближайшее время планирую поднять targetSdk в своих проектах, и миграция пока не выглядит сложной.
👍23
​​Git bisect
#разработка

Давным-давно рассказывал о таком крутейшем инструменте, как git bisect. С тех пор я много раз им пользовался, и хотелось бы, чтобы он был в арсенале как можно у большего числа разработчиков.

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

И вот на помощь нам приходит отличный, но почему-то не очень распространённый инструмент — git bisect.

Чтобы его использовать необходимо:
1) Открыть консоль git и перейти в папку проекта.
2) Ввести git checkout <commit hash>, где вместо скобок записать коммит, в котором проявилась проблема.
3) Начать процесс поиска при помощи команды git bisect start.
4) Пометить этот коммит плохим при помощи команды git bisect bad.
5) Пометить коммит, где точно нет проблемы при помощи команды git bisect good <commit hash>.
6) Далее повторяете процесс. Каждый раз git будет переключать в нужный коммит между предыдущим хорошим и плохим коммитом при помощи бинарного поиска. Собираете проект и проверяете, проявляется ли проблема. Если да, то вводите git bisect bad, если же нет, то git bisect good.
7) После завершения поиска вводите git bisect reset, чтобы вернуть репозиторий в начальное состояние.

У вас получится найти проблемный коммит за log n шагов, где n — число коммитов между первыми помеченными коммитами.
🔥26👍12👏1
​​Important Performance Metrics
#android

Попалась статья, в которой описываются ключевые метрики Android приложений. Особенно полезно изучить её прежде чем начинать оптимизировать своё приложение: как минимум, вы будете понимать, на что стоит потратить свои усилия. 😉

1️⃣ Фазы запуска приложения — важная метрика, которая видна пользователю приложения как только он открывает его. В целом, есть следующие этапы запуска приложения:

➡️ cold start — открытие приложения сразу после его установки, полного закрытия, перезапуска системы и т.д. Как раз тут и вызывается Application.onCreate(). По мнению автора, время холодного запуска должно быть меньше 500 миллисекунд, большее время заметно пользователям и может вызвать раздражение.
➡️ warm start — измеряется, начиная с Activity.onCreate() перед созданием дерева View. Его можно получить, если сделать поворот экрана, во время которого пересоздаётся Activity, ну или когда система вытесняет ваше приложение из памяти, если оно находится в фоне.
➡️ hot start — измеряется, начиная с Activity.onStart(). Его вы получаете, когда переключаетесь между приложениями.

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

2️⃣ Time to Initial Display — это время до отрисовки первого кадра вашего приложения, можно проверить при помощи ActivityTaskManager с тэгом Displayed.

3️⃣ Time to Full Display — время, когда было отрисовано всё необходимое для работы с экраном. Любопытно, что эту метруку можно не только проверить, но и настраивать при помощи reportFullyDrawn() метода Activity.

4️⃣ Frame rates — важная характеристика, которая показывает, насколько плавно работает ваше приложение. Тут есть прямая зависимость от частоты обновления экрана, и автор рекомендует взять за эталон 90 fps: следовательно, у нас есть максимум 1/90 или 11.1 миллисекунд для отрисовки одного кадра.

Больше деталей можно посмотреть в самой статье
👍13
​​Pre-inflated ViewPool для RecyclerView
#android

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

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

Для этого как раз и используется PrefetchViewPool. В статье можно почитать детальнее о том, как его применить для конкретной реализации адаптера.

У автора получилось улучшить время отображения RecyclerView с 214.19ms до 118.35ms, что, как мне кажется, весьма достойный результат. 👍🏻
👍19👎2🔥1
​​Как переместить View с клавиатурой
#новичкам #android

Показ клавиатуры и её синхронизация с отображаемыми View — довольно распространённая вещь. И хотя у нас уже появилась возможность синхронизировать показ клавиатуры и кнопок, далеко не все приложения используют эту фичу. Давайте кратко рассмотрим, какие вообще варианты у нас есть.

1️⃣ API 30 и выше — можем сделать крутую анимацию для показа клавиатуры, плавно перемещая View в нужную нам позицию.

2️⃣ API 21 – API 29View анимируются с небольшой зарежкой, но не так плавно, как в предыдущем варианте. Выглядит чуть похуже, но терпимо.

3️⃣ API 20 и ниже — анимации при показе нет, View сразу перемещается в необходимое место над клавиатурой. К счастью, подобных смартфонов становится всё меньше, и многие приложения повышают минимальный SDK.

Для того, чтобы понять позицию клавиатуры, мы должны использовать OnApplyWindowInsetsListener, в котором уже можем как раз и анимировать необходимые нам View.

Кода написать надо совсем немного, при этом вы получите красивое отображение клавиатуры на экране. Больше деталей, примеров и кода лучше взять в этой статье.
👍13👎3🔥3
​​Mock API response с Retrofit
#android

На практике частенько бывает так, что нам приходится добавлять какую-то фичу в приложение в момент, когда ещё нет backend.
В таком случае приходится делать mock для нужных нам запросов, и существует несколько вариантов:

👉 попросить backend сделать mock — вариант, в котором нам не придётся делать лишнюю работу, однако не всегда возможный, если команда backend занята иными задачами;

👉 сделать mock через Postman — хорошее решение, которое создаст имитацию реального сервера, но придётся немного изучить документацию;

👉 сделать mock через Firebase — аналогичное решение, но в рамках другого сервиса;

👉 сделать mock через Retrofit — далеко не все знают, что мы можем использовать кастомный Interceptor, чтобы переопределять нужные нам запросы и возвращать необходимый результат. Подробнее о том, как лучше это организовать в своём проекте можно почитать тут.

Можете покидать свои решения в комментариях. 😏
👍15👎2
​​10 неизвестных инструментов для Android-разработки
#android

Люблю порой читать всякие топы и рейтинги, в них иногда попадаются полезные штуки, о которых ты не знал. Вот очередная статья с неизвестными инструментами для работы с Android, и тут есть некоторые, которые захотелось поставить и потестировать. Все инструменты бесплатные и open source.

1️⃣ stackzyприложение, которое позволяет посмотреть используемые зависимости и разрешения любого приложения. Помимо того, что оно красивое, так еще и написано на современном стеке и компонентах: Compose Desktop, MVVM, Coroutines & Flow.
💡Забавный факт: приложение использует Google Sheet в качестве backend.

2️⃣ v9 — некоторые должны помнить 9-patch файлы, которые динамически и автоматически изменяют размер растровых изображений в соответствии с тем, что внутри и размером экрана. Есть подобный инструмент для Path, который делает похожие штуки.

3️⃣ Glanceинструмент для просмотра содержимого базы данных вашего приложения. Выглядит как полезный инструмент для тестирования, а подключается по аналогии с LeakCanary, которым вдохновлялись при создании этой библиотеки.

4️⃣ adb-tools-mac — всплывающее меню для работы с Android-устройствами для MacOS. Может быть полезно вашим тестировщикам (разработчиков подобный плагин есть внутри Android Studio).

5️⃣ name-that-color-desktop — почти бесполезное, но забавное приложение, которое именует за вас цвета по отправленному hex-коду. Подобное есть ещё тут, так что приложение ставить не обязательно.

6️⃣ Gradle Task Tree — Gradle plugin, который построит дерево вызванных задач для конкретной команды. Полезная вещь для дебага времени билда приложения.
🔥9👍4
​​Тулзы для анализа Android-приложений
#android #security

Тут ребята из Digital Security делятся целым набором инструментов для проверки Android-приложений. Про многие из них не слышал, уверен, что и вам будет интересно взять что-то себе на вооружение:

💡прокси — для анализа трафика используется три инструмента: BurpSuite, MitmProxy и OWASP ZAP. Рекомендуется начать работу с BurpSuite как с наиболее простого и понятного инструмента.

💡статический анализJADX для анализа классов и ресурсов, Apktool для работы с текущими ресурсами и ассетами, ByteCode Viewer — если первая тулза не справляется с декомпиляцией классов, Androguard удобен для построения графов классов.

💡динамический анализFrida для подключения на лету к приложению и внедрению в него своего кода, Objection и Medusa как доволнительный набор инструментов для Frida.

Ещё больше инструментов и скриншотов можно найти в статье у ребят. Обязательно в закладки!
🔥10👍2
​​DSL type-safe builders
#kotlin

Подробная статья, которая рассказывает о Kotlin DSL и её применении в реальных проектах.
Будет полезно, если вы никогда не слышали об этом инструменте или не понимаете, где его можно применить. Множество примеров из других приложений и проектов.

В общем, хороший кандидат для того, чтобы добавить в закладки ☺️
🔥8👍2🍓2
​​Design of Kotlin Coroutines
#kotlin

Сегодня я к вам с хорошей статьей, где автор рассказывает о том, как устроены Coroutines под капотом.

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

В статье много примеров кода, а также разбор почти всех методов для Coroutines: launch(), start(), invoke(), startCoroutineCancellable(), resumeWithCancellable(), resumeWith(), invokeSuspend(). 🤓
👍7❤‍🔥4
​​Select в Kotlin Coroutines
#kotlin

Давненько на канале не появлялось сообщений. 🙄 Но я снова с вами, и сегодня предлагаю обсудить ключевое слово select, но только не в контексте SQL-запросов, а в контексте Coroutines.

В мобильной разработке его можно использовать для кейсов, когда у нас есть несколько suspend-функций, но нас интересует результат только той, которая завершится первой.

Небольшой пример:
val winner = select<String> {
data1().onAwait { it }
data2().onAwait { it }
}

println("The winner = $winner") // prints "The winner = Hello"


Функции data1 и data2 — это простейшие вызовы с delay:
fun data1() = GlobalScope.async {
delay(1000)
"Hello"
}

fun data2() = GlobalScope.async {
delay(2000)
"World"
}


В общем, ещё один суперполезный инструмент при использовании Coroutines. Подробнее можно почитать тут.
🔥13🍾8👍5👌1🏆1
​​Дизайн система с Jetpack Compose
#compose

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

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

Кроме этого, есть ещё несколько преимуществ:
👉 общий язык между командой дизайнеров и разработчиков;
👉 единственный "источник истины" при вёрстке;
👉 изменения в нижнем слое мгновенно изменяют состояние всех остальных слоёв;
👉 расширяемость: все более сложные компоненты состоят из множества маленьких;

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

Поделитесь опытом: помогла ли вам дизайн-система улучшить процессы между командами. Или скиньте в комментариях ещё больше полезных статей с прикладным опытом для построения такой системы.
🔥8
​​Kotlin и bytecode
#kotlin

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

👉 что такое Java Virtual Machine и её спецификация;
👉 почему фичи Java и Kotlin совместимы;
👉 как выглядят основные фичи Kotlin в байткоде.
👍6🤩1
​​KMM в Beta
#kmm

Отличные новости. Пару дней назад, команда Kotlin официально перевела KMM в Beta. А это значит, что теперь не будет фундаментальных изменений в самом фреймворке, ребята работают над улучшением стабильности текущих фич.

А тут ещё Google подоспел с официальным апдейтом некоторых мультиплатформенных Jetpack-библиотек, начали с Collections и DataStore, уверен, что скоро подоспеют и другие. Вдруг мы увидим мультиплатформенный Room 😁.

Ну а я очень верю в KMM и желаю команде успехов. 😉
🔥14👍3
👌61
​​Android Studio Shortcuts. Codebase
#новичкам #android

Очередной список рекомендаций, а точнее — список горячих клавиш, которые касаются быстрого перехода по кодовой базе.
Клавиши действительно полезные, и большинство из них вы будете использовать на практике.
Вот несколько из тех сочетаний, что описывает статья.

1️⃣ Cmd + Click — одно из наиболее полезных сочетаний. При клике на функцию, вы переходите на её объявление, а при клике на интерфейс — в реализацию интерфейса. Но не все знают, что очень удобно использовать это же сочетание для навигации в Dagger + Hilt.

2️⃣ Double Shift — ещё одно удобнейшее и распространённое сочетание клавиш. Попробуйте при поиске использовать Camel case search. Например, BLPaVM вернёт BlueLinePackingViewModel. А ещё — попробуйте ввести SignInFragment#42, и вы перейдёте на 42 строку фрагмента для авторизации.

3️⃣ Cmd + Shift + F — удобнейший быстрый поиск по вашей кодовой базе.

4️⃣ Cmd + L — быстрый переход на нужную вам строку кода в вашем проекте.

5️⃣ Cmd + E — показ последний файлов с которыми вы взаимодействовали.

Буду рад, если напишите свои любимые клавиши в комментариях. ☺️
🔥9👍3
​​Как работает reified?
#kotlin

Kotlin предлагает множество крутых фичей, которые делают написание кода проще и удобнее. reified — одна из них, и так как подобная функция есть далеко не во всех языках программирования, то многие разработчики не совсем понимают, для чего им она нужна.

💡Давайте рассмотрим пару кейсов, когда мы можем сделать наш код чище и более "Kotlin-style".

С reified непосредственно связано понятие inline функций и использование generics. При их использовании может потребоваться знание того, какого типа класс мы используем. Рассмотрим пример маппинга json в нужный нам класс:

fun <T> String.toKotlinObject(): T {
val mapper = jacksonObjectMapper()
//does not compile!
return mapper.readValue(this, T::class.java)
}


Чтобы исправить ошибку при компилировании, у нас есть две опции.

1️⃣ Передавать класс в параметрах. Тогда наша функция будет выглядеть так:

fun <T: Any> String.toKotlinObject(c: KClass<T>): T {
val mapper = jacksonObjectMapper()
return mapper.readValue(this, c.java)
}


А её вызов будет таким: jsonTypeAsString.toKotlinObject(MyJsonType::class).

2️⃣ Использовать reified. Тогда всё станет сильно удобнее и красивее:

inline fun <reified T: Any> String.toKotlinObject(): T {
val mapper = jacksonObjectMapper()
return mapper.readValue(this, T::class.java)
}


А вызов будет таким: json.toKotlinObject<MyJsonType>().

Как мы видим, второй вариант выглядит гораздо более удобным для использования, хотя наш пример — довольно простая функция. В более сложных кейсах это преимущество может быть ещё заметнее.

Больше подробностей о reified можно найти в этой небольшой статье. 🤓
👍28👎1
​​Themed App Icons
#android

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

💡 Сейчас таких приложений довольно немного, а зря, ведь поддержку добавить довольно просто. Для этого необходимо прописать monochrome-атрибут в adaptive-icon.

Больше информации про иконки, про то, как сделать поддержку разных иконок приложения можно найти в этой статье.
👍122🔥1
2025/08/25 21:29:10
Back to Top
HTML Embed Code: