Forwarded from Mobile Native ️️
Mastering Execution Time Measurement in Kotlin
Статья с примерами того, как можно измерять время выполнение ваших функций в Kotlin, с помощью👇
• measureNanoTime()
• measureTimeMillis()
• measureTimeMicros()
• measureTime()
Читать (En)
Статья с примерами того, как можно измерять время выполнение ваших функций в Kotlin, с помощью👇
• measureNanoTime()
• measureTimeMillis()
• measureTimeMicros()
• measureTime()
Читать (En)
👍2
Forwarded from Android Guards
Попалась мне тут совершенно замечательная ссылка, которой не имею сил не поделиться - https://github.com/krizzsk/HackersCave4StaticAndroidSec.
Там куча ссылок на туториалы, утилиты и исследования по уязвимостями в Android. Звучит скучно да? Верно. Это был бы еще один всратый "awesome list" если бы не одно "но" - там много ссылок на нативные китайские блоги и статьи. И там действительно полезная инфа, которую просто так не загулишь, если не ищешь специально на китайском. Я давно хотел найти что-то подобное и вот оно пришло. Из полезного лично для себя, я нашел там разбор форматов различных файлов (
Там куча ссылок на туториалы, утилиты и исследования по уязвимостями в Android. Звучит скучно да? Верно. Это был бы еще один всратый "awesome list" если бы не одно "но" - там много ссылок на нативные китайские блоги и статьи. И там действительно полезная инфа, которую просто так не загулишь, если не ищешь специально на китайском. Я давно хотел найти что-то подобное и вот оно пришло. Из полезного лично для себя, я нашел там разбор форматов различных файлов (
AndroidManifest.xml, resources.arsc и т.п.) и материалы по статическому анализу. Всем 你好 ;)GitHub
GitHub - krizzsk/HackersCave4StaticAndroidSec: A comprehensive resource for Android static analysis and vulnerability assessment.…
A comprehensive resource for Android static analysis and vulnerability assessment. Tutorials, tools, and resources for identifying and mitigating security vulnerabilities in Android applications. -...
🔥4
Forwarded from Mobile Native ️️
Building an Android System Design Architecture for Efficient Image Uploads with Clean Architecture
Пример проектирования архитектуры для приложения, которое могло бы позволить загружать большое количество картинок на сервер без блокировки UI и с доп. кейсами.
Без примера кода, но с разбивкой на слои и детальным описанием связей и работы каждого слоя.
Читать (En)
Пример проектирования архитектуры для приложения, которое могло бы позволить загружать большое количество картинок на сервер без блокировки UI и с доп. кейсами.
Без примера кода, но с разбивкой на слои и детальным описанием связей и работы каждого слоя.
Читать (En)
👍1
Forwarded from Kotlin Multiplatform Broadcast (Кирилл Розов)
Ключевые слова in и out. А так же что такое ковариантность и контрвариантность (12 мин)
Погружение в вариативность Generic типов в Kotlin. Тема непростая, но может раскрыть вам новые грани гибкости вашего кода и его строго типизации
Погружение в вариативность Generic типов в Kotlin. Тема непростая, но может раскрыть вам новые грани гибкости вашего кода и его строго типизации
👍2💩2
Forwarded from Android Broadcast (Кирилл Розов)
Обновили официальную документацию по обработке изменения конфигурации (поворот экрана, смена языка и пр.). Добавили советы по использованию Jetpack API, как работать с этим из Compose и лучшие практик
👍2
Forwarded from Mobile Compose
#Article #Medium #Compose
[Eng] How to Handle Automatic Content Resizing when keyboard is visible in Jetpack Compose
Неплохая статья с разбором того, как можно адаптировать контент приложения под открытие/закрытие клавиатуры на Compose.
[Eng] How to Handle Automatic Content Resizing when keyboard is visible in Jetpack Compose
Неплохая статья с разбором того, как можно адаптировать контент приложения под открытие/закрытие клавиатуры на Compose.
Medium
How to Handle Automatic Content Resizing when keyboard is visible in Jetpack Compose
As Android developers, we have all encountered the problem of the keyboard overlapping the content of our app, which can be frustrating for…
👍1
Forwarded from Android Broadcast (Кирилл Розов)
Вышла вторая Dev Preview Android 14, которую можно ознаменовать как "еще больше ограничений для разработчиков" и радость для магазинов приложений!
👉 Выдача доступа приложения к отдельным фото и видео, вместо всех (аналогично на iOS)
👉 Credential Manager - единая точка работы с sign-in. Через Jetpack это API уже портировано на Android 4.4+
👉 Дополнительные ограничения по запуску Activity из фона
👉 Больше ограничений на фоновую работу
👉 Новое API в PackageInstaller позволит каждый раз не запрашивать установку приложений, а сделать это один раз для приложений. Альтернативным магазинам станет жить проще
👉 Региональные настройки для всей системы и для каждого приложения
👉 Разработчики смогут определить когда делаются скриншоты
Все изменения я разберу в отдельных постах
@android_broadcast #android14
👉 Выдача доступа приложения к отдельным фото и видео, вместо всех (аналогично на iOS)
👉 Credential Manager - единая точка работы с sign-in. Через Jetpack это API уже портировано на Android 4.4+
👉 Дополнительные ограничения по запуску Activity из фона
👉 Больше ограничений на фоновую работу
👉 Новое API в PackageInstaller позволит каждый раз не запрашивать установку приложений, а сделать это один раз для приложений. Альтернативным магазинам станет жить проще
👉 Региональные настройки для всей системы и для каждого приложения
👉 Разработчики смогут определить когда делаются скриншоты
Все изменения я разберу в отдельных постах
@android_broadcast #android14
👍3
Forwarded from AppFiles - Mobile Development
SuperImage - это Android-приложение для улучшения качества изображений на основе нейронной сети, созданное с использованием фреймворка глубокого обучения MNN и Real-ESRGAN. Входное изображение обрабатывается тайлами на графическом процессоре устройства с использованием предварительно обученной модели Real-ESRGAN. Затем плитки объединяются в окончательное изображение с высоким разрешением. Это приложение требует поддержки Vulkan или OpenCL и Android 7 или выше.
SuperImage на GitHub: https://github.com/Lucchetto/SuperImage
Платформа: Android
⭐️: 486
SuperImage на GitHub: https://github.com/Lucchetto/SuperImage
Платформа: Android
⭐️: 486
👍3
Forwarded from Android Guards
Даже если на устройстве есть root доступ, команды
#aht
adb push/pull все равно будут работать в пользовательском режиме. Это значит, что не выйдет скачать или отправить файлы в директории доступные только суперпользователю. Но выход есть. Вместо adb push будет cat file.txt | adb shell su -c "dd of=/data/file.txt", а для замены adb pull - adb shell su -c "dd if=/data/file.txt" >> file.txt. В целом, так можно выполнить любую команду с правами root - adb shell su -c "<command>".#aht
🤔6👍3👎1
Forwarded from Ra'Reilly - Заметки про Ktor и не только (Osip Fatkullin)
Обычно мы на всех проектах добавляем тип сборки QA. Это такая сборка, которая максимально близка к релизной, но может включать в себя дебаг-панель и позволяет подключиться к приложению через дебаггер.
И вот недавно оказалось, что схема не работает. QA сборки не обфусцируются, а значит не сильно отличаются от дебажных. Причём не понятно в какой момент отвалилась обфускация и из-за чего это произошло.
Расследование привело к багтреккеру гугла: "AGP 7.2.0 onwards does not obfuscate our built app" и issue закрыто как Won't fix (Intended behavior)🙂
Дело в том, что флаг
Решение подсказали там же в issue. Новый API, добавленный в AGP7.0 4.2 позволяет вклиниться в процесс подготовки артефактов сборки. Можно подменять, добавлять и изменять промежуточные файлы, например: манифест, APK и даже использовать совсем чёрную магию — модифицировать уже скомпилированные классы. Хотелось когда-нибудь модифицировать один класс в библиотеке, чтобы не ждать исправления бага?
Но сейчас не об этом. Нам интересен манифест. С помощью этого API мы можем дописать любой текст в смердженный манифест, в частности и флаг
👨🦽 Результат можно увидеть в фиксе для gradle-infrastructure или в отдельном сниппете.
P.S. Помимо флага в манифесте приходится ещё руками менять значение
#agp #snippet
И вот недавно оказалось, что схема не работает. QA сборки не обфусцируются, а значит не сильно отличаются от дебажных. Причём не понятно в какой момент отвалилась обфускация и из-за чего это произошло.
Расследование привело к багтреккеру гугла: "AGP 7.2.0 onwards does not obfuscate our built app" и issue закрыто как Won't fix (Intended behavior)
Дело в том, что флаг
isDebuggable = true теперь отключает обфускацию и по задумке инженеров гугла так должно было работать всегда. Ведь вы не сможете бегать по коду дебаггером, если он отличается от исходников, какой же это тогда получается debuggable? То что раньше была возможна обфускация с isDebuggable = true это изначально ошибочное поведение и AGP никогда не должен был так работать. Видимо ошибка показалась настолько очевидной, что фикс даже не упомянули в release notes, а как известно every change breaks someones workflow, что и случилось.Решение подсказали там же в issue. Новый API, добавленный в AGP
Но сейчас не об этом. Нам интересен манифест. С помощью этого API мы можем дописать любой текст в смердженный манифест, в частности и флаг
debuggable.P.S. Помимо флага в манифесте приходится ещё руками менять значение
BuildConfig.DEBUG ведь он тоже зависит от isDebuggable.#agp #snippet
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5👍2🤔2
Forwarded from Kotlin Multiplatform Broadcast (Кирилл Розов)
KMM Utilities - набор различных утилит для Kotlin
👉 ApiResult - монада для оборачивания результата операции. Схоже с kotlin.Result, но больше возможностей.
👉 Common - Дополнения к Kotlin stdlib
👉 Datetime - Все чего не хватает и kotlinx.datetime, Java Calendar и DateTime API.
👉 Coroutines: Расширения для Coroutines & Flows API. Расширения для Android.
👉 ApiResult - монада для оборачивания результата операции. Схоже с kotlin.Result, но больше возможностей.
👉 Common - Дополнения к Kotlin stdlib
👉 Datetime - Все чего не хватает и kotlinx.datetime, Java Calendar и DateTime API.
👉 Coroutines: Расширения для Coroutines & Flows API. Расширения для Android.
👍4🔥2👎1
Forwarded from Dev Easy Notes
Два друга @JvmWildcard и @JvmSuppressWildcards.
В комментах накинули вопрос про @JvmSuppressWildcards. Тоже довольно неочевидная штука, но порой приходится разбираться. Суть в чем, Java и Kotlin полностью совместимы, что означает что из Java можно вызывать Kotlin, и наоборот. На стыке этих двух языков начинаются приколы, например в Kotlin все типы делятся на Nullable и NotNullable, а в Java такого разделения нет.
Работа дженериков тоже немного отличается. Буквально в предыдущем посте я описывал, что ковариантность и контравариантность в Kotlin может работать на уровне классов, а не ссылок. И вот пример:
Как видите в Box дженерик помечен как out, что означает ковариантность на уровне всех объектов. Только это работает на уровне Kotlin. Если попытаемся вызвать метод
В целом все не так страшно, однако иногда охото подкрутить это поведение. Например, мы не хотим, чтобы в методе
Делаем в Kotlin:
Получаем в Java:
Делаем в Kotlin:
Получаем в Java:
Сравните эти две полученные функции с дефектным поведением и суть станет ясна.
Где это нужно на практике? У меня такое было только при работе с Dagger. Фишка в чем, в том что Dagger работает на базе Kapt. Если вдруг не знали, то kapt работает в два приседания. Сперва он перегоняет весь код в Java Stub и только потом генерит нужный код. Поэтому он такой долгий и по этой причине иногда нужно делать подсказки компилятору, когда пишем модули на Kotlin. В противном случае кодогенератор начинает чудить и падать.
В комментах накинули вопрос про @JvmSuppressWildcards. Тоже довольно неочевидная штука, но порой приходится разбираться. Суть в чем, Java и Kotlin полностью совместимы, что означает что из Java можно вызывать Kotlin, и наоборот. На стыке этих двух языков начинаются приколы, например в Kotlin все типы делятся на Nullable и NotNullable, а в Java такого разделения нет.
Работа дженериков тоже немного отличается. Буквально в предыдущем посте я описывал, что ковариантность и контравариантность в Kotlin может работать на уровне классов, а не ссылок. И вот пример:
class Box<out T>(val value: T)
fun box(value: Integer): Box< Integer> = Box(value)
fun unbox(box: Box<Number>): Number = box.valueКак видите в Box дженерик помечен как out, что означает ковариантность на уровне всех объектов. Только это работает на уровне Kotlin. Если попытаемся вызвать метод
box из Java, то он вернет Box без дженерика. Это как бы немного нарушает логику ковариантности которую обещает Kotlin. При этом в методе unbox автоматически появится wildcard. В итоге в Java получим вот это:Box box(Integer value)
Number unbox(Box<? extend Number>)В целом все не так страшно, однако иногда охото подкрутить это поведение. Например, мы не хотим, чтобы в методе
unbox автоматически проставлялся wildcard. Или же напротив проставлялся в результатах функции, в методе box. И вот для этого, нужны наши волшебные аннотации. Кафк всегда, лучше на примере.Делаем в Kotlin:
fun box(value: Integer): Box<@JvmWildcard Integer> = Box(value)Получаем в Java:
Box<? extend Integer> box(Integer value)Делаем в Kotlin:
fun unbox(box: Box<@JvmSuppressWildcards Number>): Number = box.valueПолучаем в Java:
Number unbox(Box<Number> box)Сравните эти две полученные функции с дефектным поведением и суть станет ясна.
Где это нужно на практике? У меня такое было только при работе с Dagger. Фишка в чем, в том что Dagger работает на базе Kapt. Если вдруг не знали, то kapt работает в два приседания. Сперва он перегоняет весь код в Java Stub и только потом генерит нужный код. Поэтому он такой долгий и по этой причине иногда нужно делать подсказки компилятору, когда пишем модули на Kotlin. В противном случае кодогенератор начинает чудить и падать.
👍3🔥2🤯2
Forwarded from Ra'Reilly - Заметки про Ktor и не только (Osip Fatkullin)
Насмотренность — важный навык в работе дизайнера. Это то что помогает быть в тренде, учиться на чужом опыте, черпать вдохновение, отличать хороший дизайн от плохого, критически оценивать свою работу и так далее. Нет вы не ошиблись каналом, просто я считаю, что насмотренность важна и разработчикам. Чем больше чужого кода смотришь — тем лучше пишешь свой. Просто потому что больше новых приёмов и концепций узнаёшь, улучшаешь свой скилл владения языком. С хэштегом #насмотренность буду писать про всё интересное на что наткнулся при просмотре open-source проектов. Это первый пост :)
👀 Companion object
Чаще всего
☝️ Json в kotlinx.serialization
Это класс, но мы можем использовать его как-будто он
✌️CoroutineContext.Key в kotlinx.coroutines
CoroutineContext вообще интересная штука. По сути это что-то между Map и Set. Каждый элемент контекста хранится в
Каждый ключ должен быть singleton'ом и ключ должен быть у каждого элемента контекста (
У каждого элемента контекста
👀 Companion object
Чаще всего
companion object используется просто как замена статическим методам и полям из Java. А ведь companion object это в первую очередь object и как у любого другого объекта у него может быть имя и он может реализовывать интерфейсы и наследоваться от других классов. Сегодня будет два примера таких companion object'ов.☝️ Json в kotlinx.serialization
Это класс, но мы можем использовать его как-будто он
object:val result = Json.decodeFromString("42")
Всё потому что companion object у Json реализует класс Json:companion object Default : Json(JsonConfiguration(), EmptySerializersModule())Зачем так сложно, если можно было бы просто объявить
object Json? Потому что тогда не было бы возможности создать свой инстанс, а когда Json это класс, такая возможность остаётся.✌️CoroutineContext.Key в kotlinx.coroutines
CoroutineContext вообще интересная штука. По сути это что-то между Map и Set. Каждый элемент контекста хранится в
CoroutineContext по ключу и получить элементы контекста можно через оператор get.Каждый ключ должен быть singleton'ом и ключ должен быть у каждого элемента контекста (
Job, CoroutineDispatcher и т.д.). Идеальная задача для companion object!У каждого элемента контекста
companion object это реализация CoroutineContext.Key и смотрите какая красота получается в совокупности с оператором get у CoroutineContext:val job = coroutineContext[Job]Выглядит как-будто получаем элемент контекста по типу. На самом деле используется
val dispatcher = coroutineContext[CoroutineDispatcher]
companion object c типом Key, объявленный в этих классах. Например, в Job он выглядит так:companion object Key : CoroutineContext.Key<Job>
🔥7👍2🤔2
Forwarded from Mobile Native ️️
10 Useful Kotlin Extension Functions for Android Developer
Еще один большой набор полезных Kotlin Extension функций для удобного использования.
👉 Print to Logcat
👉 View Visibility
👉 Toast Message
👉 Snackbar Message
👉 Hide Keyboard
👉 dp and px conversion
👉 Digit, Alphabetic, and Alphanumeric Check
👉 isNull, ifNull
👉 Date Formatter
Читать (En)
Еще один большой набор полезных Kotlin Extension функций для удобного использования.
👉 Print to Logcat
👉 View Visibility
👉 Toast Message
👉 Snackbar Message
👉 Hide Keyboard
👉 dp and px conversion
👉 Digit, Alphabetic, and Alphanumeric Check
👉 isNull, ifNull
👉 Date Formatter
Читать (En)
🔥3👍2❤1
Forwarded from Записки разработчицы (Anna Zharkova)
Врываемся с хорошими новостями в эту пятницу. Открыт для обсуждения proposal о внесении статиков в Kotlin
https://github.com/Kotlin/KEEP/issues/348
https://github.com/Kotlin/KEEP/issues/348
👍1🤔1
Учебное пособие по Jetpack Compose: реализация полностью настраиваемого UI со сложной анимацией.
🗄 Waveform Animation
🗄 Action Panel
🗄 Collapsing Header
🗄 Moving between screens
🗄 Improving Jetpack Compose performance with Compose Compiler Metrics
Please open Telegram to view this post
VIEW IN TELEGRAM
Medium
Jetpack Compose Tutorial: Replicating Dribbble Audio App Part 1
Implementing a fully custom UI with complex animations: Waveform Animation
👍2🔥1
Forwarded from Kotlin Multiplatform (Kostya)
https://medium.com/@bchoi000/sunflower-flavor-kmm-get-started-with-kotlin-multiplatform-mobile-9dc014c45b95
Все, наверное, видели официальное приложение гугла Android Sunflower with Compose, которое демонстрирует лучшие практики в разработке приложений под Андроид, по мнению гугл! 🙌
Так вот, Ethan Choi взял и по шагам перевел приложение на Kotlin Multiplatform и реализовал нативный UI на iOS. 🤩
Очень круто! 🥳
Все, наверное, видели официальное приложение гугла Android Sunflower with Compose, которое демонстрирует лучшие практики в разработке приложений под Андроид, по мнению гугл! 🙌
Так вот, Ethan Choi взял и по шагам перевел приложение на Kotlin Multiplatform и реализовал нативный UI на iOS. 🤩
Очень круто! 🥳
👍2🔥2
Forwarded from Mobile Native ️️
Easy caching Android + Kotlin + Flow
Статья с примером организации кеширования (Cached Source) с разными опциями(NEVER, IF_FAILED, IF_HAVE, ONLY, CACHED THEN LOAD) в связке Kotlin + Coroutines + Flow.
Пример кода на GitHub → Universal Cache
Читать (En)
Статья с примером организации кеширования (Cached Source) с разными опциями(NEVER, IF_FAILED, IF_HAVE, ONLY, CACHED THEN LOAD) в связке Kotlin + Coroutines + Flow.
Пример кода на GitHub → Universal Cache
Читать (En)
🔥6👍2
Forwarded from red_mad_dev
・Senior iOS-разработчик red_mad_robot Аня Кочешкова рассказала, чем отличаются три менеджера зависимостей, в каких случаях и для каких задач подойдёт тот или иной. Аня подробно объяснила, что такое семантическое версионирование, как устроены модули кода и в чём разница между динамическими и статическими библиотеками. Материал будет полезен джунам, которые только начали погружаться в разработку.
・Head of Android red_mad_robot Central Asia Влад Бауэр поделился опытом, как решил нехватку iOS-разработчиков на одном из внутренних проектов. Он придумал решение: пошарил часть кода и перенёс его в Kotlin Multiplatform Mobile. Спойлер: у Влада получилось, и теперь он рассказывает о нюансах, с которыми ему пришлось столкнуться.
#ios #android #kotlin
・Head of Android red_mad_robot Central Asia Влад Бауэр поделился опытом, как решил нехватку iOS-разработчиков на одном из внутренних проектов. Он придумал решение: пошарил часть кода и перенёс его в Kotlin Multiplatform Mobile. Спойлер: у Влада получилось, и теперь он рассказывает о нюансах, с которыми ему пришлось столкнуться.
#ios #android #kotlin
👍2🔥2
Forwarded from Android Broadcast (Кирилл Розов)
Инструкция по реализации собственного виджета для выбора времени (Time Picker) на Jetpack Compose
#compose
#compose
👍3🔥2😱1
Артур Артиков, тимлид в компании MobileUp, делится опытом внедрения компонентного подхода для борьбы со сложностью в Android-приложениях:
🗄 Боремся со сложностью в Android-приложениях
🗄 Реализуем экраны с помощью библиотеки Decompose
🗄 Организуем навигацию с помощью библиотеки Decompose
Please open Telegram to view this post
VIEW IN TELEGRAM
Хабр
Компонентный подход. Боремся со сложностью в Android-приложениях
Представьте, что вы начали разработку нового Android-приложения. Поначалу особых проблем не будет. Вы реализовали лишь самые базовые функции. Экранов немного, и все они простые. Вам легко...
👍1🔥1🙊1