Manual DI
DI-фреймворки продолжают появляться как грибы после дождя. Теперь рекомендуют использовать Metro, но всё чаще можно услышать, что люди принципиально отказываются от каких-либо библиотек для реализации DI. Так как в моей команде мы в основном делаем переиспользуемые общие модули, мы тоже давно отказались от DI-фреймворков. И знаете что? Мы вообще не испытываем из-за этого каких-либо проблем.
Тут я вспомнил про свой KMP-сэмпл и решил, что будет круто показать всё это на примере и заменить Koin в проекте. Но хорошо, что я не начал делать это раньше времени: буквально на докладе про сравнение DI-фреймворков с Podlodka Android Crew я узнал, что Александр Власюк уже всё сделал раньше и даже заслал pull request🌐
Примечательно, что Manual DI не только даёт compile-time safety по сравнению с Koin (без всяких плагинов), но даже количество строк кода в проекте сократилось😲
Понятно, что это всего лишь пример. Если использовать Koin глобально, то кода с Manual DI придётся писать больше. Однако я придерживаюсь подхода, при котором DI должен быть изолирован внутри модуля, а зависимости должны быть объявлены явно, чтобы можно было легко переиспользовать этот модуль где угодно.
А вы что думаете, стоят ли DI-фреймворки, чтобы их изучать и постоянно мигрировать проект на все более новые решения❓
#DI #Kotlin #KMP
DI-фреймворки продолжают появляться как грибы после дождя. Теперь рекомендуют использовать Metro, но всё чаще можно услышать, что люди принципиально отказываются от каких-либо библиотек для реализации DI. Так как в моей команде мы в основном делаем переиспользуемые общие модули, мы тоже давно отказались от DI-фреймворков. И знаете что? Мы вообще не испытываем из-за этого каких-либо проблем.
Тут я вспомнил про свой KMP-сэмпл и решил, что будет круто показать всё это на примере и заменить Koin в проекте. Но хорошо, что я не начал делать это раньше времени: буквально на докладе про сравнение DI-фреймворков с Podlodka Android Crew я узнал, что Александр Власюк уже всё сделал раньше и даже заслал pull request
Примечательно, что Manual DI не только даёт compile-time safety по сравнению с Koin (без всяких плагинов), но даже количество строк кода в проекте сократилось
Понятно, что это всего лишь пример. Если использовать Koin глобально, то кода с Manual DI придётся писать больше. Однако я придерживаюсь подхода, при котором DI должен быть изолирован внутри модуля, а зависимости должны быть объявлены явно, чтобы можно было легко переиспользовать этот модуль где угодно.
А вы что думаете, стоят ли DI-фреймворки, чтобы их изучать и постоянно мигрировать проект на все более новые решения
#DI #Kotlin #KMP
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍21🔥6🗿3
Изменение конфигурации в прошлом
Еще пару лет назад я заметил, что если в AndroidManifest явно прописать все варианты изменения конфигурации в configChanges, то Compose сможет самостоятельно подхватить подавляющее большинство изменений без какого-либо дополнительного кода. Но тогда я был непонят сообществом, и никто это всерьез не воспринял😨
Теперь же об этом заговорили инженеры из Google, рекомендую посмотреть доклад с Droidcon🟥 . Начиная с compileSdk 36, можно одной строчкой игнорировать все текущие и будущие причины пересоздания Activity из-за изменения конфигурации.
Это позволит нам полностью избавиться от андроидовской ViewModel и инкапсулировать нашу логику в обычных классах. При этом это не значит, что Activity никогда не будет пересоздаваться, изменение конфигурации лишь одна из причин. Но в таких случаях состояние можно сохранить только с помощью SavedInstanceState, ViewModel здесь бы не помогла.
А вы что думаете, готовы ли вы забыть об изменении конфигурации в Android и о ViewModel в частности?
#Android #Compose
Еще пару лет назад я заметил, что если в AndroidManifest явно прописать все варианты изменения конфигурации в configChanges, то Compose сможет самостоятельно подхватить подавляющее большинство изменений без какого-либо дополнительного кода. Но тогда я был непонят сообществом, и никто это всерьез не воспринял
Теперь же об этом заговорили инженеры из Google, рекомендую посмотреть доклад с Droidcon
Это позволит нам полностью избавиться от андроидовской ViewModel и инкапсулировать нашу логику в обычных классах. При этом это не значит, что Activity никогда не будет пересоздаваться, изменение конфигурации лишь одна из причин. Но в таких случаях состояние можно сохранить только с помощью SavedInstanceState, ViewModel здесь бы не помогла.
А вы что думаете, готовы ли вы забыть об изменении конфигурации в Android и о ViewModel в частности?
#Android #Compose
Please open Telegram to view this post
VIEW IN TELEGRAM
👍29👎6✍4🔥4😎3😁1
Проблема KSP
Kotlin Symbol Processing — современная технология для генерации кода, но насколько безопасно использовать библиотеки с KSP в проекте?
При обновлении зависимостей мы попали в следующую ловушку: не все библиотеки, которые мы используем, поддержали KSP2, и при этом новая версия Room крашится, если явно отключить поддержку KSP2 в gradle.properties. Сейчас ещё можно обойти проблему, понизив версии, но начиная с AGP 9 и Kotlin 2.3.0 KSP1 перестанет работать.
Что с этим делать?
🔘 Можно включить режим ждуна и мониторить, когда авторы сторонних библиотек добавят поддержку, но не факт, что это произойдёт.
🔘 Форкнуть библиотеку и реализовать поддержку самостоятельно, что может оказаться нетривиальной задачей, если раньше с KSP вы не работали.
🔘 Избавиться от зависимости на такую библиотеку. Если она не глубоко интегрирована в проект, то проще выбрать этот путь, тогда при очередном обновлении зависимостей проблем не возникнет.
А используете ли вы в своих проектах библиотеки с KSP, кроме Room и Dagger?
#KSP #Android
Kotlin Symbol Processing — современная технология для генерации кода, но насколько безопасно использовать библиотеки с KSP в проекте?
При обновлении зависимостей мы попали в следующую ловушку: не все библиотеки, которые мы используем, поддержали KSP2, и при этом новая версия Room крашится, если явно отключить поддержку KSP2 в gradle.properties. Сейчас ещё можно обойти проблему, понизив версии, но начиная с AGP 9 и Kotlin 2.3.0 KSP1 перестанет работать.
Что с этим делать?
А используете ли вы в своих проектах библиотеки с KSP, кроме Room и Dagger?
#KSP #Android
Please open Telegram to view this post
VIEW IN TELEGRAM
👍21❤1🤔1
Советы по работе с AI-агентами для начинающих
На днях посмотрел отличный доклад от Евгения Сатурова на Podlodka AI Crew о страхах разработчиков и типичных ошибках при работе с AI-агентами.
Я делал точно такие же ошибки, поэтому поделюсь советами с вами:
🔘 Выбирайте лучшую доступную модель на сегодня, не используйте auto-режим в Cursor и подобных инструментах.
🔘 Не пишите задачи напрямую. Формулируйте мета-промпт с описанием задачи для модели, чтобы она составила вам подробный таск-промпт.
🔘 В мета-промпте пишите, что вы хотите сделать, а не как, избегайте чрезмерной специфики.
🔘 Прикладывайте весь необходимый контекст. Плохо, когда модель начинает делать семантический поиск по проекту.
🔘 Не дробите задачу слишком сильно — это неэффективно. Современные модели могут достаточно долго работать автономно, главное не вылезти за контекст. По возможности используйте сабагентов.
🔘 Не вступайте в споры с моделью и не правьте код руками. Просто откажитесь от сгенерированного кода, обновите таск-промпт, правила проекта и попробуйте снова.
💬 Делитесь в комментариях своими лучшими практиками по работе с AI-агентами.
#AI
На днях посмотрел отличный доклад от Евгения Сатурова на Podlodka AI Crew о страхах разработчиков и типичных ошибках при работе с AI-агентами.
Я делал точно такие же ошибки, поэтому поделюсь советами с вами:
#AI
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍19🤡18😡2❤1🥴1
Мы в команде создаём переиспользуемые общие модули между приложениями, и общая логика ключевых модулей шарится между Android и iOS. Это, безусловно, несёт в себе много плюсов, но и добавляет много сложностей.
Например, так сложилось, что в Android все модули находятся в монорепозитории, а в iOS каждый отдельный модуль — это отдельный репозиторий из-за особенностей менеджера пакетов Swift (SPM).
Поэтому мы предоставляем общий фреймворк через SPM, который iOS-разработчики могут подключить как отдельную зависимость.
И если вы шарите код только одной библиотеки, всё достаточно просто. Но когда появляется вторая и третья библиотека, начинаются проблемы. В KMP рекомендуется использовать так называемый umbrella-модуль, чтобы не тащить рантайм KMP в каждый отдельный фреймворк.
Но это несёт в себе одну большую проблему: всё, что мы экспортируем, попадает в одно пространство имён. Соответственно, одинаково названные классы при интеропе в Objective-C будут переименованы: к одному из классов добавится нижнее подчёркивание. И изменения в одном модуле легко могут сломать другой🙃
Мы пока полноценно не решили эту проблему, но выработали правило: обязательно указывать имя модуля для всех публичных сущностей, которые экспортируются в Objective-C. Но с приходом Swift Export проблема должна отпасть, так как там можно будет указывать отдельный импорт для каждой библиотеки.
Это далеко не единственная проблема, с которой мы столкнулись. Если тема интересна — ставьте реакции, и я напишу ещё посты по теме.
#KMP #iOS
Например, так сложилось, что в Android все модули находятся в монорепозитории, а в iOS каждый отдельный модуль — это отдельный репозиторий из-за особенностей менеджера пакетов Swift (SPM).
Поэтому мы предоставляем общий фреймворк через SPM, который iOS-разработчики могут подключить как отдельную зависимость.
И если вы шарите код только одной библиотеки, всё достаточно просто. Но когда появляется вторая и третья библиотека, начинаются проблемы. В KMP рекомендуется использовать так называемый umbrella-модуль, чтобы не тащить рантайм KMP в каждый отдельный фреймворк.
Но это несёт в себе одну большую проблему: всё, что мы экспортируем, попадает в одно пространство имён. Соответственно, одинаково названные классы при интеропе в Objective-C будут переименованы: к одному из классов добавится нижнее подчёркивание. И изменения в одном модуле легко могут сломать другой
Мы пока полноценно не решили эту проблему, но выработали правило: обязательно указывать имя модуля для всех публичных сущностей, которые экспортируются в Objective-C. Но с приходом Swift Export проблема должна отпасть, так как там можно будет указывать отдельный импорт для каждой библиотеки.
Это далеко не единственная проблема, с которой мы столкнулись. Если тема интересна — ставьте реакции, и я напишу ещё посты по теме.
#KMP #iOS
Please open Telegram to view this post
VIEW IN TELEGRAM
👍77❤5🔥3🤡3😎2👏1
Forwarded from Android Broadcast
Алексей Панов @kotlin_adept , опытный мобильный разработчик, реализующий приложения с применением KMP, проведет собеседование на позицию Kotlin Multiplatform разработчика в прямом эфире на YouTube канале "Android Broadcast" (время и дата будут объявлены позже)
Требования к кандидату:
👉 Опыт в мобильной разработки
👉 Опыт с Kotlin
👉 Понимание как происходит разработка приложений с KMP
Будет теория и практика. Это ваш шанс проявить себя и заявить на большую аудиторию о своих возможностях!
Если решили принять участие - заполняйте анкету!
#AndroidBroadcast
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥16👎2
Проблема версионирования
Продолжаем тему KMP, и прежде чем перейти к следующей проблеме, хочется поговорить о том, как мы делим наши библиотеки для предоставления общего кода в iOS.
Мы разбиваем библиотеку на две части: core и compose. В core-модуле, соответственно, лежит вся логика, а в compose — только вёрстка. При этом каждый модуль мы делим на пакеты api/internal и с помощью правила detekt запрещаем использовать публичные сущности из пакета internal.
Также мы стараемся избегать использования сторонних библиотек, кроме ключевых, таких, как Ktor, SQLDelight, но в качестве исключения мы приняли решение использовать Decompose. Это позволяет значительно упростить интеграцию с общим кодом в iOS, ведь всё, что нужно сделать — это смаппить жизненный цикл. А дальше, в зависимости от текущего состояния навигации, показываем тот или иной экран и отправляем события в компонент. Это позволяет скрыть все детали реализации и меньше страдать из-за проблем с интеропом.
Однако то, что хорошо работает на iOS, создаёт проблемы на Android, так как в публичном интерфейсе core-модуля приходится раскрывать все интерфейсы компонентов, чтобы иметь возможность обращаться к ним из ui-модуля. Хотя для интеграции модуля в Android достаточно передать верхнеуровневый компонент из core-модуля в экран, никто не мешает разработчикам обращаться к другим публичным сущностям.
Одним из решений здесь видится использование специальных аннотаций, например
В такой парадигме поддерживать обратную совместимость API, а тем более ABI, почти нереально. Поэтому, поскольку это внутренние библиотеки, мы приняли решение поднимать мажорную версию только в том случае, если реально ломаем точки интеграции API. Для iOS мы просто создаём задачи на доработку, где указываем, что поменялось в этом релизе и что требует обновления.
Процесс получился далёким от идеала, но пока что это работает🙃
#KMP #iOS
Продолжаем тему KMP, и прежде чем перейти к следующей проблеме, хочется поговорить о том, как мы делим наши библиотеки для предоставления общего кода в iOS.
Мы разбиваем библиотеку на две части: core и compose. В core-модуле, соответственно, лежит вся логика, а в compose — только вёрстка. При этом каждый модуль мы делим на пакеты api/internal и с помощью правила detekt запрещаем использовать публичные сущности из пакета internal.
Также мы стараемся избегать использования сторонних библиотек, кроме ключевых, таких, как Ktor, SQLDelight, но в качестве исключения мы приняли решение использовать Decompose. Это позволяет значительно упростить интеграцию с общим кодом в iOS, ведь всё, что нужно сделать — это смаппить жизненный цикл. А дальше, в зависимости от текущего состояния навигации, показываем тот или иной экран и отправляем события в компонент. Это позволяет скрыть все детали реализации и меньше страдать из-за проблем с интеропом.
Однако то, что хорошо работает на iOS, создаёт проблемы на Android, так как в публичном интерфейсе core-модуля приходится раскрывать все интерфейсы компонентов, чтобы иметь возможность обращаться к ним из ui-модуля. Хотя для интеграции модуля в Android достаточно передать верхнеуровневый компонент из core-модуля в экран, никто не мешает разработчикам обращаться к другим публичным сущностям.
Одним из решений здесь видится использование специальных аннотаций, например
@InternalVisibilityAPI, которые будут предупреждать пользователя о том, что это внутренний API библиотеки.В такой парадигме поддерживать обратную совместимость API, а тем более ABI, почти нереально. Поэтому, поскольку это внутренние библиотеки, мы приняли решение поднимать мажорную версию только в том случае, если реально ломаем точки интеграции API. Для iOS мы просто создаём задачи на доработку, где указываем, что поменялось в этом релизе и что требует обновления.
Процесс получился далёким от идеала, но пока что это работает
#KMP #iOS
Please open Telegram to view this post
VIEW IN TELEGRAM
👍28❤2
Это уже мое четвертое публичное собеседование, в котором я стараюсь раскрыть основные аспекты работы с современными технологиями:
Сегодня на собеседовании будет задачка на ревью проекта с плохим кодом, но с упором на KMP. И по ходу эфира обсудим все нюансы интеграции общего кода с iOS.
Если вам интересна эта тема, обязательно приходите на прямой эфир, будет интересно! А в конце я смогу ответить на все ваши вопросы.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥48❤3🤡3
Материалы для углублённого изучения KMP
По мотивам вчерашнего собеса хочу посоветовать классные доклады, которые помогут вам глубже разобраться в принципах работы Kotlin Multiplatform и Kotlin Native, а также лучше понять нюансы интеропа со Swift-кодом.
На английском:
🔘 ЖЦ объектов в Kotlin/Native
🔘 Процесс компиляции в Kotlin/Native, отличия статических и динамических фреймворков
🔘 Проблемы текущего интеропа и возможные пути улучшения
🔘 Разница между Kotlin и Swift concurrency
🔘 Принцип работы Swift Export
На русском:
🔘 Совместная работа Kotlin/Native GC и ARC в Swift
🔘 iOS Memory Management
#KMP
По мотивам вчерашнего собеса хочу посоветовать классные доклады, которые помогут вам глубже разобраться в принципах работы Kotlin Multiplatform и Kotlin Native, а также лучше понять нюансы интеропа со Swift-кодом.
На английском:
На русском:
#KMP
Please open Telegram to view this post
VIEW IN TELEGRAM
👍29🔥14😁1
Стоит ли переходить с Room на SQLDelight?
На данный момент обе библиотеки поддерживают KMP. Если раньше особого выбора не было, то теперь многие могут задаться вопросом: стоит ли вообще переходить с Room?
Я считаю, что нет, не стоит. Конечно, у каждой библиотеки есть свои преимущества и недостатки, но, на мой взгляд, у SQLDelight их заметно больше:
🔘 Нельзя задать разные имена для таблицы в БД и сгенерированного класса. Если вы придерживаетесь общепринятого синтаксиса именования таблиц, то имена сгенерированных классов будут выглядеть просто ужасно.
🔘 Видимость сгенерированных файлов также нельзя регулировать — все они будут public.
🔘 Нет поддержки suspend-функций, приходится явно менять диспетчер для каждого запроса. (оказывается есть, в настройках плагина есть свойство generateAsync)
🔘 Нельзя сразу сгенерировать класс с отношением many-to-many или другими связями, например, чтобы получить фильм со списком актёров, придётся делать дополнительный маппинг на стороне Kotlin.
🔘 Нет автоматических миграций, как в Room (но в целом это зло).
🔘 Очень скудная документация.
Из плюсов я бы выделил следующее:
🟢 Небольшие таблицы можно сразу смаппить в доменные типы с помощью Type Projections.
🟢 Нет магии аннотаций, все запросы пишутся явно.
🟢 Нет зависимости на KSP и плагины компилятора.
🟢 Поддерживается больше таргетов, чем в Room.
🟢 Может работать не только с SQLite.
В общем, я пришёл к выводу, что Room для меня выигрывает у SQLDelight, и мигрировать с него я бы не стал. Но и возвращаться обратно, если вы уже перешли, особого смысла тоже не вижу.
А что думаете вы, какая из библиотек вам ближе❓
#Room #SQLDelight #KMP
На данный момент обе библиотеки поддерживают KMP. Если раньше особого выбора не было, то теперь многие могут задаться вопросом: стоит ли вообще переходить с Room?
Я считаю, что нет, не стоит. Конечно, у каждой библиотеки есть свои преимущества и недостатки, но, на мой взгляд, у SQLDelight их заметно больше:
Из плюсов я бы выделил следующее:
В общем, я пришёл к выводу, что Room для меня выигрывает у SQLDelight, и мигрировать с него я бы не стал. Но и возвращаться обратно, если вы уже перешли, особого смысла тоже не вижу.
А что думаете вы, какая из библиотек вам ближе
#Room #SQLDelight #KMP
Please open Telegram to view this post
VIEW IN TELEGRAM
❤25👍12❤🔥3
10 кругов ада, или как вручную перенести все фотки из-за аккаунта разработчика
Так вышло, что фотографирую я не очень часто, и только сейчас у меня закончилось место на Google Диске. Теперь в каждом своём приложении Google показывает страшные баннеры и вынуждает купить подписку🤑
Что ж, убедили, идём покупать. Но с русским платёжным профилем ничего не купить. Зачем тогда предлагали? Ну да ладно.
Пытаемся поменять платёжный профиль, но этого сделать нельзя из-за активного аккаунта разработчика🤨
Аккаунт я давно забросил и все приложения там удалил, но Google заодно «удалил» и мой аккаунт, так как я не подтвердил личность.
Пишу в техподдержку, чтобы аккаунт удалили окончательно и я смог поменять платёжный профиль. На что получаю ответ: сделать это нельзя, если на аккаунте нет активных приложений😵
Тут я понял, что ситуация патовая и надо что-то делать. Одним из вариантов было создать новый аккаунт для фоток и заодно перенести все фото на Яндекс Диск.
Окей, качаем через Google Takeout архив со всеми фотками. Метаданные EXIF лежат там в отдельном JSON-файле, соответственно, ни данных о дате, ни геолокации в фотке нет, и нужно это как-то восстанавливать.
Я нашёл скрипт на Python, который это делает, и пришлось ещё немного подвайбкодить, чтобы всё заработало...
Вот такой вот квест получился. А если бы аккаунта разработчика не было, все бы решилось проще, так что думайте😏
#Offtop
Так вышло, что фотографирую я не очень часто, и только сейчас у меня закончилось место на Google Диске. Теперь в каждом своём приложении Google показывает страшные баннеры и вынуждает купить подписку
Что ж, убедили, идём покупать. Но с русским платёжным профилем ничего не купить. Зачем тогда предлагали? Ну да ладно.
Пытаемся поменять платёжный профиль, но этого сделать нельзя из-за активного аккаунта разработчика
Аккаунт я давно забросил и все приложения там удалил, но Google заодно «удалил» и мой аккаунт, так как я не подтвердил личность.
Пишу в техподдержку, чтобы аккаунт удалили окончательно и я смог поменять платёжный профиль. На что получаю ответ: сделать это нельзя, если на аккаунте нет активных приложений
Тут я понял, что ситуация патовая и надо что-то делать. Одним из вариантов было создать новый аккаунт для фоток и заодно перенести все фото на Яндекс Диск.
Окей, качаем через Google Takeout архив со всеми фотками. Метаданные EXIF лежат там в отдельном JSON-файле, соответственно, ни данных о дате, ни геолокации в фотке нет, и нужно это как-то восстанавливать.
Я нашёл скрипт на Python, который это делает, и пришлось ещё немного подвайбкодить, чтобы всё заработало...
Вот такой вот квест получился. А если бы аккаунта разработчика не было, все бы решилось проще, так что думайте
#Offtop
Please open Telegram to view this post
VIEW IN TELEGRAM
1🤯22😁8❤3👍1😨1
Зоопарк кроссплатформенных фреймворков
Думаю, вы все слышали про такие фреймворки, как Flutter и Expo (React Native) для разработки кроссплатформенных мобильных приложений и не только. Но, разумеется, таких фреймворков существует значительно больше, и по сей день появляются новые решения.
Давайте рассмотрим некоторые из них:
Valdi — фреймворк от Snapchat, где UI пишется на TypeScript DSL, который напрямую компилируется в нативные вьюшки. Разработчики обещают производительность, сопоставимую с нативными приложениями, так как фреймворк не использует ни WebView, ни JavaScript Bridge. Поддерживает Android, iOS и macOS.
ArkUI-X — проект, расширяющий декларативный UI-фреймворк для разработки приложений под HarmonyOS NEXT и позволяющий добавить поддержку компиляции под Android и iOS. Это ещё один фреймворк, использующий TypeScript, а точнее его надмножество ArkTS.
Skip — единственный платный для корпоративного использования фреймворк, который изначально представлял собой транспилятор из Swift в Kotlin и позволял переводить нативные iOS-приложения на SwiftUI в Android-приложения с Jetpack Compose. Но в новом режиме Fuse Skip начал использовать недавно вышедший Swift SDK для Android, что позволит уйти от прямой транспиляции кода по крайней мере для бизнес-логики.
Если честно, я не верю в широкое распространение этих фреймворков, но будет интересно посмотреть, к чему всё это приведёт. А что думаете вы? Попробовали бы один из этих фреймворков для разработки мобильных приложений?
#Crossplatform #Frameworks
Думаю, вы все слышали про такие фреймворки, как Flutter и Expo (React Native) для разработки кроссплатформенных мобильных приложений и не только. Но, разумеется, таких фреймворков существует значительно больше, и по сей день появляются новые решения.
Давайте рассмотрим некоторые из них:
Valdi — фреймворк от Snapchat, где UI пишется на TypeScript DSL, который напрямую компилируется в нативные вьюшки. Разработчики обещают производительность, сопоставимую с нативными приложениями, так как фреймворк не использует ни WebView, ни JavaScript Bridge. Поддерживает Android, iOS и macOS.
ArkUI-X — проект, расширяющий декларативный UI-фреймворк для разработки приложений под HarmonyOS NEXT и позволяющий добавить поддержку компиляции под Android и iOS. Это ещё один фреймворк, использующий TypeScript, а точнее его надмножество ArkTS.
Skip — единственный платный для корпоративного использования фреймворк, который изначально представлял собой транспилятор из Swift в Kotlin и позволял переводить нативные iOS-приложения на SwiftUI в Android-приложения с Jetpack Compose. Но в новом режиме Fuse Skip начал использовать недавно вышедший Swift SDK для Android, что позволит уйти от прямой транспиляции кода по крайней мере для бизнес-логики.
Если честно, я не верю в широкое распространение этих фреймворков, но будет интересно посмотреть, к чему всё это приведёт. А что думаете вы? Попробовали бы один из этих фреймворков для разработки мобильных приложений?
#Crossplatform #Frameworks
👍12😐7
Как улучшить дальность сканирования кодов маркировки
Библиотеки вроде Google ML Kit, ZXing или его аналога на C++ со стандартными настройками камеры имеют довольно посредственную дальность сканирования, приходится подносить камеру очень близко, чтобы хоть что-то отсканировать. Особенно это касается акцизных марок нового образца. При этом, если взглянуть на коммерческие решения, они работают на голову выше.
Как можно улучшить ситуацию?
🟢 Как ни странно, можно попробовать уменьшить разрешение камеры, двух мегапикселей более чем достаточно для распознавания.
🟢 Увеличить параметр zoomRatio в камере по-умолчанию, например, установить 1.5f вместо 1f.
🟢 Реализовать автоматический зум к потенциальным кодам. Для этого в ML Kit появились настройки enableAllPotentialBarcodes и ZoomSuggestionOptions.
🟢 Ограничить размер зоны сканирования.
Наверняка можно придумать что-то ещё. Хотелось бы спросить совета у тех, кто уже сталкивался с подобной задачей, есть идеи, что еще можно сделать?
P.S. Обучение собственной модели не предлагать🙂
#Camera #BarcodeReader
Библиотеки вроде Google ML Kit, ZXing или его аналога на C++ со стандартными настройками камеры имеют довольно посредственную дальность сканирования, приходится подносить камеру очень близко, чтобы хоть что-то отсканировать. Особенно это касается акцизных марок нового образца. При этом, если взглянуть на коммерческие решения, они работают на голову выше.
Как можно улучшить ситуацию?
Наверняка можно придумать что-то ещё. Хотелось бы спросить совета у тех, кто уже сталкивался с подобной задачей, есть идеи, что еще можно сделать?
P.S. Обучение собственной модели не предлагать
#Camera #BarcodeReader
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥21👍5❤🔥3😈1
Посмотрите на код на изображении. Эта composable-функция используется на экране с камерой, чтобы сделать полупрозрачную рамку по периметру. Как думаете, в чем тут проблема?
Вместо прозрачного выреза на некоторых старых устройствах будет чёрный прямоугольник.
Я уже когда-то сталкивался с этой проблемой, когда Compose еще не было и в помине. При работе с Android Canvas проблема заключалась в использовании PorterDuff.Mode.CLEAR.
В прошлый раз эту проблему в AndroidView удалось пофиксить, переведя отрисовку на hardware-accelerated layer:
Но как сделать то же самое в Compose? Если просто получить текущий View через LocalView, то, вероятно, мы не получим нужного поведения, так как изменим layerType для верхнеуровневой вьюшки.
Мне ничего лучше не пришло в голову, чем сделать composable-функцию враппер, в которой контент будет прокидываться в AbstractComposeView, где уже и будет происходить изменение layerType.
Таким образом, чтобы пофиксить проблему, достаточно будет обернуть код на изображении в этот враппер. Если нужен код враппера, напишите в комментариях.
P.S. Как думаете, когда люди уже перестанут использовать семилетние смартфоны Xiaomi?
#Android #Canvas #Compose
Я уже когда-то сталкивался с этой проблемой, когда Compose еще не было и в помине. При работе с Android Canvas проблема заключалась в использовании PorterDuff.Mode.CLEAR.
В прошлый раз эту проблему в AndroidView удалось пофиксить, переведя отрисовку на hardware-accelerated layer:
setLayerType(LAYER_TYPE_HARDWARE, null)
Но как сделать то же самое в Compose? Если просто получить текущий View через LocalView, то, вероятно, мы не получим нужного поведения, так как изменим layerType для верхнеуровневой вьюшки.
Мне ничего лучше не пришло в голову, чем сделать composable-функцию враппер, в которой контент будет прокидываться в AbstractComposeView, где уже и будет происходить изменение layerType.
Таким образом, чтобы пофиксить проблему, достаточно будет обернуть код на изображении в этот враппер. Если нужен код враппера, напишите в комментариях.
P.S. Как думаете, когда люди уже перестанут использовать семилетние смартфоны Xiaomi?
#Android #Canvas #Compose
🤯22🔥3😭3👍2
🔥 Уже понимаете, что Kotlin — это будущее автоматизации? Тогда не пропустите наш вебинар
24 ноября в 20:00 мск! Роман Сперанский расскажет, почему Kotlin — это ключ к быстрым, чистым и умным тестам, а также поделится практическими советами для вашего развития.
Регистрируйтесь по ссылке🔗
Хотите перейти к реальной практике и освоить автоматизацию на Kotlin?
Начинайте обучение сейчас и получите 5% скидку!
Онлайн-курс включает 22 занятия, домашние задания, живые вебинары, 100 часов практики и два проекта для портфолио — всё под руководством эксперта с 16-летним опытом.
Узнайте все детали курса на сайте🔗
24 ноября в 20:00 мск! Роман Сперанский расскажет, почему Kotlin — это ключ к быстрым, чистым и умным тестам, а также поделится практическими советами для вашего развития.
Регистрируйтесь по ссылке
Хотите перейти к реальной практике и освоить автоматизацию на Kotlin?
Начинайте обучение сейчас и получите 5% скидку!
Онлайн-курс включает 22 занятия, домашние задания, живые вебинары, 100 часов практики и два проекта для портфолио — всё под руководством эксперта с 16-летним опытом.
Узнайте все детали курса на сайте
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6👎4🤝1
Android Gradle Library Plugin
Если вы вдруг пропустили, то для KMP-проектов появился отдельный Android-плагин для library-модулей, который значительно уменьшает количество Gradle-тасок и ускоряет как конфигурацию проекта, так и сборку.
Особенности плагина:
🔘 В нём убрали поддержку flavor и build type.
🔘 Отключена Java-компиляция по умолчанию.
🔘 Отключены по умолчанию unit и инструментальные тесты (не забудьте про них, а то будет как в этом посте).
Мы уже подключили его в пару наших проектов, и результаты действительно впечатляющие🔥
🟢 Количество тасок при прогоне unit-тестов уменьшилось более чем в 4 раза, и во столько же раз удалось ускорить их выполнение.
🟢 С Android Lint похожая история: там количество запускаемых тасок сократилось в 2 раза, и в 1,5 раза удалось получить прирост скорости.
В общем, миграция определённо того стоит, но посмотрите внимательно на текущие ограничения в документации, возможно, вам пока этот плагин не подойдёт.
#Android #KMP #Gradle
Если вы вдруг пропустили, то для KMP-проектов появился отдельный Android-плагин для library-модулей, который значительно уменьшает количество Gradle-тасок и ускоряет как конфигурацию проекта, так и сборку.
Особенности плагина:
Мы уже подключили его в пару наших проектов, и результаты действительно впечатляющие
В общем, миграция определённо того стоит, но посмотрите внимательно на текущие ограничения в документации, возможно, вам пока этот плагин не подойдёт.
#Android #KMP #Gradle
Please open Telegram to view this post
VIEW IN TELEGRAM
👍24😱2
Jetpack Navigation 3
Только сейчас дошли руки более пристально взглянуть на новую Jetpack Navigation 3.
Помню, многие жаловались, что Decompose весь такой сложный, а навигация от Google простая. Но что мы видим в новой версии:
NavBackStack, NavEntry, NavDisplay, NavEntryDecorator, SceneStrategy и так далее🫠
При этом, несмотря на то что вышла стабильная версия, много кода всё равно придётся писать дополнительно:
Хочешь навигацию по табам? Пиши код для управления бэкстеком.
Нужен BottomSheet? Пиши декоратор.
Необходимо привязать ЖЦ ViewModel к экрану? Подключай отдельную библиотеку.
Нужна вложенная навигация? Разбирайся с кастомными сценами.
В общем, вы поняли. Довольно много бойлерплейта придётся копировать из примеров на GitHub, чтобы всё завести. Если хотите, чтобы я сделал подробное сравнение с Decompose, вы знаете, что надо сделать👍
Ну и напишите, планируете ли вы миграцию с любой другой библиотеки на Navigation 3? Интересно будет узнать ваше мнение.
#Compose #Navigation
Только сейчас дошли руки более пристально взглянуть на новую Jetpack Navigation 3.
Помню, многие жаловались, что Decompose весь такой сложный, а навигация от Google простая. Но что мы видим в новой версии:
NavBackStack, NavEntry, NavDisplay, NavEntryDecorator, SceneStrategy и так далее
При этом, несмотря на то что вышла стабильная версия, много кода всё равно придётся писать дополнительно:
Хочешь навигацию по табам? Пиши код для управления бэкстеком.
Нужен BottomSheet? Пиши декоратор.
Необходимо привязать ЖЦ ViewModel к экрану? Подключай отдельную библиотеку.
Нужна вложенная навигация? Разбирайся с кастомными сценами.
В общем, вы поняли. Довольно много бойлерплейта придётся копировать из примеров на GitHub, чтобы всё завести. Если хотите, чтобы я сделал подробное сравнение с Decompose, вы знаете, что надо сделать
Ну и напишите, планируете ли вы миграцию с любой другой библиотеки на Navigation 3? Интересно будет узнать ваше мнение.
#Compose #Navigation
Please open Telegram to view this post
VIEW IN TELEGRAM
2👍98🔥14❤7🤯4
QA Mobile MeetUp
Если вы тестируете мобильные приложения, приходите на митап Спортса” и Selectel.
Обсудим насущное: сбор ферм девайсов, генерацию тестовых данных, ревью тест-кейсов и тестирование рекламы.
📍оффлайн в Москве и онлайн
🗓5 декабря, 18:00
👉 Смотрите программу и регистрируйтесь: https://sprts.cc/0ulpbs
Реклама. АО "Селектел". erid:2W5zFJSg6Ta
Если вы тестируете мобильные приложения, приходите на митап Спортса” и Selectel.
Обсудим насущное: сбор ферм девайсов, генерацию тестовых данных, ревью тест-кейсов и тестирование рекламы.
📍оффлайн в Москве и онлайн
🗓5 декабря, 18:00
👉 Смотрите программу и регистрируйтесь: https://sprts.cc/0ulpbs
Реклама. АО "Селектел". erid:2W5zFJSg6Ta
👍4