Обновить
145.37

Android *

Пишем под самую популярную мобильную ОС

Сначала показывать
Порог рейтинга

Как я сделал blur и линзу в Jetpack Compose

Всем привет! Меня зовут Владимир, я мобильный разработчик в «Финам». В одном из недавних проектов нужно было добавить в интерфейс Jetpack Compose визуальные эффекты поверх контента, например размытый хедер или движущуюся «лупу». 

Обычно такие приемы встречаются в играх, где весь экран — это фактически полотно для рисования OpenGL. В классической XML-разметке UI я с таким не сталкивался, поэтому пришлось довольно глубоко погрузиться во внутреннюю кухню Compose. Этот разбор может быть полезен тем, кто решает похожие задачи.

Сначала на Stack Overflow я нашел неплохой пример создания эффекта размытия на определенном участке экрана — к сожалению, это решение не было универсальным и зависело от верстки. Однако мое внимание привлекли два класса из фреймворка: RenderNode и GraphicsLayer

Если коротко, можно захватить часть экрана через GraphicsLayer, а в RenderNode записать контент. Но перед этим его можно обработать. После обработки метод drawWithContent() выводит результат в canvas. 

Сначала я попытался модифицировать эффект размытия из ответа на Stack Overflow, затем сделал размытие в форме круга, который движется вслед за пальцем, и постепенно пришел к окончательному варианту с движущейся прозрачной линзой. Код для отрисовки эффекта я показал в статье.

В результате можно получить эффект линзы, которая будет перемещаться за пальцем, если водить им по экрану. 

Какие выводу я могу сделать:

  • в Compose можно делать крутые визуальные эффекты, если покопаться в RenderNode;

  • это неочевидный, но мощный инструмент, он дает простор для кастомизации.

Мой пример не самый изобретательный, но способ, который я показал, открывает почти безграничные возможности для реализации визуальных эффектов в Android-разработке, чем мы в «Финам» и пользуемся очень активно в наших финтех-проектах. Итоговый результат оформил в GitHub-репозитории — берите и пробуйте в своих проектах.

Теги:
0
Комментарии0

Открываем набор на бесплатное обучение по IT-направлениям по программе Альфа-Будущее Кампус

Открываем новый набор на обучение по разным IT-направлениям в рамках образовательной программы Альфа-Будущее Кампус

Сроки программ — от 3 месяцев до полугода, за которые вы научитесь создавать современные цифровые продукты под руководством ведущих экспертов Альфа-Банка в разработке, системной аналитике, QA и бизнес-аналитике.

Выбирайте курс, переходите по ссылке, изучайте программу и подавайте заявку. Успейте присоединиться до 27 октября! ❤️

Обучение бесплатно.

А если хотите узнать, есть ли польза от курсов, как проходит обучение (на примере факультета аналитики), и подойдет ли вам онлайн-обучение IT-специальности, читайте нашу статью по ссылке ниже. На примере факультета системной аналитики рассказали, как готовится программа, как проводятся собеседования с людьми и помогло ли ученикам обучение:

Можно ли стать аналитиком, отучившись в онлайн-школе?
С каждым годом в наших командах появляется всё больше перспективных тестировщиков, разработчиков и а...
habr.com
Теги:
+2
Комментарии0

Разбор полётов: вся правда о падениях Android-приложений

Почему Android-приложение вылетает с ошибкой и что на самом деле происходит под капотом? Абакар, главный технический лидер разработки в Альфа-Банке, раскрывает наглядно и увлекательно этапы срабатывания необработанных исключений: от простого деления на ноль до глубоких слоёв архитектуры Android

В статье «Почему моё Android-приложение крашится?» — понятные пошаговые разборы, примеры реальных трейс-лодов, ссылки на исходный код Android и даже инсайты, почему приложение лучше сразу завершить, чем пытаться спасти после критической ошибки.

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

Теги:
0
Комментарии0

Вспомнил холивары на первой работе на тему: что такое Activity?

Тогда, среди Android-разработчиков, в моде была MVC и общение было примерно такое:

"Activity - это контроллер" - говорили одни.

"Activity - это вью" - говорили другие.

"Activity - это модель" - так к сожалению никто не говорил, иначе было бы еще интереснее 😁

Позиции противоположные и бескомпромиссные, противостояние зацикливалось и вызывало бурю эмоций. Пока не договорились (читай как одни продавили других)

Кто из них прав?

Никто.

Или и те и другие.

Правильный же ответ такой:

Я создатель приложения и какую роль я дам этому классу(Activity) такую он и будет выполнять.

Это если смотреть со стороны архитектуры приложения.

А если смотреть со стороны OS Android, то Activity - это интерфейс через который пользовательское приложение взаимодействует с операционной системой.

Вот и всё :)

P.S. А какие холивары вспоминаются вам?)

Теги:
+3
Комментарии0

Пост о том как я разработчиков нанимал, история из жизни :)

Однажды мне написали из IT-компании что занимается разработкой решений для бизнеса под ключ, в общем аутсорс, и попросили меня помочь им с наемом.

У меня большой опыт в мобильной разработке, в основном нативный Android приправленный мультиплатформой на Compose Multiplatform и Flutter.

Руководитель компании попросил меня помочь сформировать команду Android-разработки на доработку и поддержку достаточно масштабного и сложного проекта X.

Проект тащил свое приятное но от того не менее сложное Legacy: многомодульность, Clean Architecture, DI, MVVM, Kotlin, Coroutines, Flow работа с БД и клиент-серверное взаимодействие - в общем популярный набор современного бизнес-приложения.

Строго говоря у меня было две задачи:
1. Помочь джуниору разобраться в проекте чтобы он мог уже что-то делать
2. Набрать команду нативных Android-разработчиков

Условия усложнялись тем, что компания что до этого разрабатывала проект не очень-то шла на контакт и обе стороны принимали друг-друга в штыки. По этому сам проект и задачи передавались со скрипом и негативными эмоциями, "проект теперь ваш, вот вы и разбирайтесь, мы сделали конфетку, там все понятно" - говорили одни, "у нас команда профессионалов и задачи задерживаются потому что вы написали чрезмерно сложный недо-код" - говорили другие, а владелец продукта говорил- "ничего не волнует делайте как хотите за все уплочено" (бизнес и конкуренция как ни крути 😁)

На тот момент у компании уже было пару молодых Android-джуниоров и мидл на других проектах, плюс один на проекте X, и хотелось нанять еще крепких мидлов, сеньера, и парочку стажеров на проект. Эмоции эмоциями, а работа должна быть сделана, и чтобы ее сделать нужны люди способные её сделать за приемлемый оклад и другие печеньки от компании.

Ситуацию в целом обрисовал.. (хотя ситуация конечно масштабнее там еще и менеджмент с загонкой джунов и эйчар структура направленная на формирование командного духа и внутреннего обучения.. ( как я вижу из своего опыта и то и другое скорее мешает чем помогает в моменты когда надо работу работать и должно быть сделано еще вчера ). Вот хорошая метафора пришла: ситуация как в "Лебедь, Рак и Щука", воз - это работа, а все остальные это Лебедь, Рак и Щука.)

Идем дальше:

Эйчары стали лить на меня трафик из соискателей на должность Android-разработчика. И на протяжении 2-х недель я каждый день собеседовал по 2-3 кандидата, иногда 1-го. Уровень у всех очень отличался. Приходили как совсем свежие пирожки прямо после курсов, так и уже матерые обкатанные на серьезных проектах колобки. У меня был стек проекта и потому вопросы тоже считай были сформированы, диалог строился так: Привет-привет, расскажи про свой опыт, и от этого опыта погнали ветвиться по темам в сторону нужных компетенций и стека. С кем-то укладывались в 30-минут, с кем-то залипали на 2 часа. Т.е. с кем-то шли дальше в глубину, а с кем-то прошли по верхам и на этом все.

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

Чтобы как-то передавать то что я узнавал в процессе собеседования о кандидатах, мы ввели оценку, грубо говоря число от 1 до 5, насколько человек подходит на проект + моя рекомендация. Дальше уже другие люди делали какой-то оффер на работу, или не делали.

В итоге за 2 недели мы наняли 5 человек, + тот разработчик что изначально был на проекте с моей (и божьей) помощью вкатился в проект и начал работу по задаче.

На этом история не закончилась, их ждал неизбежный онбординг, притирка и командообразование, но это уже совсем другая история..

Я еще пару недель занимался онбордингом на проекте + выступал адвокатом разработчиков + переводчиком с менеджерского на разработческий и обратно, та еще задачка 😁.

1-н нанятый стажер в итоге не потянул и отвалился, остальные 5-ро продолжили работу, уже без меня, а я отправился дальше :)

Теги:
Всего голосов 3: ↑1 и ↓20
Комментарии2

Проблема: Кадровый голод по специалистам, и при этом рекордные количества откликов на вакансии.

Причина: Плохая воронка наема специалиста (по аналогии с воронкой продаж, хорошие воронки способствуют продажам, а плохие нет), читай как - существующий процесс наема не помогает нанять специалиста, притом что специалистов на рынке более чем достаточно.

Общее решение: Изменить процесс наема так чтобы он помогал нанять специалиста для решения задач бизнеса.

Конкретные варианты решения:

  1. Использовать зарекомендовавшие себя решения в других воронках\процессах получения чего-либо. Например сарафанное радио и нетворкинг, кумовщину и рефералки, при этом отказаться от существующих фильтров в пользу доверия на старте.

  2. Устранить причину мешающую текущему процессу наема. Например сократить цепочку ЛПР-ов на пути соискателя до оптимума.

    (Сейчас это авто-скрипт, эйчар(или ряд эйчаров), собеседующий специалист(или ряд специалистов), представитель команды(или ряд представителей), опционально тут еще какие-то посредники, и вот тут уже можно выйти на работу и работать 😁. Причем на каждом этапе у лже-ЛПР-ов есть цель отсеять человека на основании формального фильтра. Тогда как лучшие работники обычно "неформалы" ибо они про работу работать как Стив Возняк, а не про продукт(себя) продавать как Стив Джобс. Очевидно что не каждая птица долетит даже до середины.. 😢)

    Оптимум - это ван ту ван, один ЛПР-соискатель на одного ЛПР-нанимателя. Собеседовать можно сколько угодно, но в конце один ответственный человек собирает всю информацию в кучу (и это не оценки и выжимки специалистов, а прям сесть и посмотреть портфолио, видео собеседования, пересказ нейронки прочитать как минимум по этому видео, переписку, на свою текущую ситуацию по задачам и срокам посмотреть и т.д.) и на основе всех имеющихся данных принять полноценное решение.

    ЛПР - это тот кто принимает решение что считает лучшим на этот момент, а не тот который работает по прописанному скрипту (иначе это не ЛПР, а человек которого настоящий ЛПР назначил отрабатывать строго по скрипту 😜).

  3. Устранить еще одну причину мешающую процессу наема. Например монолитность условий для прохождения собеседования. Можно искать пол жизни рыцаря на белом коне, до момента когда ни конь ни рыцарь уже будут не нужны, а можно взять то что само приползло и докрутить его под свои хотелки уже здесь и сейчас (то что само приползло должно быть согласно на докрутку, чтобы ни одно живое существо не пострадало в процессе наема 😁).

P.S. Все 3 варианта решения на самом деле про одно и то же, только заход с разных сторон: убрать не то что мешает обрабатывать заявки на чиле, в пол уха, левой пяткой, а убрать то что действительно мешает нанять сотрудника для решения конкретных задач. (Да стало много спама, ну и что? Разве то что много спама говорит о том что среди спама нет специалистов способных делать работу? Нет. Как раз таки в этом и заключается задача\работа нанимателя - нанять сотрудника в этих конкретных условиях. Ну да, придется поработать. Соискатель, наниматель и работодатель в одной лодке как ни крути, если кто-то не хочет грести, то далеко ли уплывет такая лодка?🛶)

Хорошего дня, наема и трудоустройства!

Обнял 🤗

Теги:
Всего голосов 7: ↑4 и ↓3+1
Комментарии2

Дело не в том как ты проходишь собеседование

Дело в том хочет человек тебя нанять или нет

Т.е. проходишь ты дальше или нет основывается не на твоих желаниях и знаниях, а на желаниях и знаниях собеседующего

Так что не парься, будь счастлив 😁

Воспринимай собеседования не как путь именно к этой работе, а как путь к чему-то вообще :)

В любом случае этот шаг делает тебя на шаг ближе к цели

Если ты не прошел собес, то выбор простой: сражайся с этим или наслаждайся этим, и даже если сражаешься, то насладись сражением 😁

P.S. И так во всём..

Теги:
Всего голосов 11: ↑7 и ↓4+5
Комментарии3

Я проснулся, делал зарядку и размышлял о поиске работы, и вот что я осознал:

Эйчары не понимают бизнес.

Бизнес не понимает эйчаров.

Эйчары не понимают технарей.

Технари не понимают эйчаров.

Бизнес не понимает технарей.

Технари не понимают бизнес.

Как следствие - эйчары нанятые бизнесом чтобы нанять непонятных для них технарей, нанимают еще хуже чем нанял бы бизнес, потому что эйчары не понимают ни бизнес, ни технарей.

Делегирование делегированием, а эффективность эффективностью.

Еще:

Бизнес конкурирует с бизнесом.

Эйчары конкурируют с эйчарами.

Технари конкурируют с технарями.

И все конкурируют со всеми.

Как следствие - на технических собесах технари с обеих сторон стремятся доминировать друг над другом. Так как решение о наеме принимает собеседующая сторона, то она имеет преимущество над соискателем и ему приходится подстраиваться.

Как следствие, на технических собеседованиях не может быть никакой объективной оценки, идеальный кандидат здесь - не человек который решает реальные задачи, а человек который идеально подстраивается под собеседующих.

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

Выводы:

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

Бизнес который делегирует наем рано или поздно оказывается в положении "свой среди чужих, чужой среди своих", фактически самым ценным ресурсом компании - людьми - теперь владеет не Бизнес, а Технарь и HR.

Такие дела.

Вот еще интересные мысли о наеме, с которых все началось:

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

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

Понимают ли они то что происходит во всей полноте? Похоже что нет, иначе процесс был бы устроен другим образом.

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

Т.е. фактически компания которая дала отказ соискателю, затратила ресурсы, обучила соискателя, и передала его другой компании. Вот что происходит на самом деле.

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

А теперь вернись к началу, вероятно теперь станет понятно откуда взялись такие тезисы :)

P.S.
Похоже всё это не является проблемой только потому, что получается микро-коммунизм в наеме. Одна компания обучает соискателей для другой, и та в свою очередь делает так же. По сути работает не система наема в компании, а побочные эффекты от нескольких систем наема разных компаний.

Откуда такие мысли:

Я уже 12 лет как в теме, и устраивался на работу сам, и искал людей на свои проекты, и собеседовал как технарь(в Android разработке) на проекты бизнеса. В общем я пощупал этого слона с разных сторон, и теперь когда я снова в активном поиске - это сложилось в объемную картину.

Теги:
Всего голосов 7: ↑5 и ↓2+4
Комментарии14

WhatsApp сканирует сеть?

Совершенно случайно наткнулся на интересное:

У меня дома стриггерился алерт: мой домашний сервачок (он же роутер) помимо всего прочего отслеживает количество уникальных от-forward'енных $src_ip + $dst_ip + $dst_port – и алертит, когда их количество превышает некоторый порог.

И вот за последние сутки с моего телефона + телефона жены 2560 + 4082 уникальных пар $dst_ip + $dst_port (где 602x22 ниже – это соединения на 22 порт на 602 разных IP-адреса):

kate-mobile.lan (4082 IP+port pairs): 3117 TCP (1534x443, 602x22, 261x80, 237x554, 220x53, 29x23, 28x983, 21x553, 20x179, 12x1443, 9x5222, 6x5228, 4x4460, 4x21, 2x571, 2x9243, 2x240, 2x383, 2x185, 2x260, 2x299, 2x237, 2x336, 2x131, 2x512, 1x464, 1x734, 1x4416, 1x371, 1x10, 1x863, 1x895, 1x759, 1x815, 1x178, 1x830, 1x271, 1x838, 1x707, 1x629, 1x174, 1x1003, 1x894, 1x3237, 1x887, 1x962, 1x603, 1x855, 1x241, 1x494, 1x540, 1x181, 1x352, 1x454, 1x373, 1x654, 1x56, 1x646, 1x175, 1x876, 1x810, 1x556, 1x395, 1x483, 1x697, 1x212, 1x34, 1x588, 1x348, 1x605, 1x680, 1x460, 1x401, 1x224, 1x143, 1x161, 1x104, 1x655, 1x872, 1x521, 1x459, 1x911, 1x705, 1x317, 1x377, 1x807, 1x323, 1x893, 1x866, 1x142, 1x1001, 1x170, 1x920, 1x843, 1x209, 1x463, 1x156, 1x569, 1x952, 1x701, 1x184, 1x597, 1x389, 1x647, 1x8543, 1x487, 1x624, 1x537, 1x814, 1x259, 1x578, 1x26, 1x904, 1x751, 1x652, 1x795, 1x234, 1x671, 1x45, 1x4477, 1x307, 1x635, 1x651, 1x227, 1x806, 1x752, 1x203, 1x220, 1x582, 1x568, 1x153, 1x844, 1x402), 965 UDP (379x443, 278x53, 116x554, 83x123, 38x22, 22x23, 7x2002, 6x983, 4x179, 2x4123, 2x512, 2x21, 2x553, 1x363, 1x652, 1x654, 1x1003, 1x299, 1x307, 1x377, 1x680, 1x807, 1x804, 1x966, 1x685, 1x240, 1x463, 1x655, 1x806, 1x45, 1x383, 1x336, 1x153, 1x260, 1x28, 1x241, 1x603)
mobile.lan (2560 IP+port pairs): 1899 TCP (814x443, 405x22, 171x554, 168x80, 160x53, 23x983, 18x179, 18x1443, 15x23, 10x553, 9x5222, 6x21, 5x7275, 3x5228, 2x19302, 1x759, 1x37, 1x629, 1x685, 1x581, 1x582, 1x10000, 1x142, 1x250, 1x846, 1x125, 1x872, 1x657, 1x8543, 1x604, 1x90, 1x727, 1x567, 1x911, 1x739, 1x810, 1x4477, 1x866, 1x26, 1x491, 1x10, 1x156, 1x626, 1x178, 1x422, 1x977, 1x155, 1x12, 1x402, 1x683, 1x21007, 1x306, 1x595, 1x184, 1x4416, 1x472, 1x14, 1x904, 1x166, 1x165, 1x753, 1x988, 1x4434, 1x11, 1x28, 1x317, 1x622, 1x535, 1x718, 1x686, 1x637, 1x207, 1x244, 1x153, 1x7000, 1x8443, 1x966, 1x383, 1x5223, 1x985, 1x161, 1x994, 1x395, 1x898, 1x39, 1x592, 1x6447), 661 UDP (307x443, 168x53, 81x554, 36x123, 24x22, 10x23, 6x983, 6x179, 4x19302, 3x553, 3x21, 1x153, 1x685, 1x626, 1x155, 1x592, 1x19000, 1x491, 1x306, 1x472, 1x125, 1x8443, 1x28, 1x966)

Поставил себе PCAPdroid на телефон, и выяснилось, что WhatsApp (я им совсем не пользуюсь – установлен по необходимости):

  • За последний месяц съел 23 MB Wi-Fi трафика.

  • За сегодняшний день съел 92 MB Wi-Fi трафика.

  • Постоянно открывает соединения на разные IP и всякие мутные порты (ssh, ntp, ftp).

Хотелось бы верить, что это какая-то очередная защита от блокировок или вроде того, но, учитывая недавние истории про слежку за пользователями на Android, что-то не очень верится. :)

Как-то более глубоко исследовать эту ситуацию, честно говоря, нет желания (да и наверняка он подобными сканированиями занимается только изредка, чтобы не привлекать к себе лишнего внимания) – поэтому всё выше написанное исключительно JFYI, без каких-либо интересных подробностей.

P.S.: Большая просьба не воспринимать это как очередную рекламу в пользу всем известного мессенджера, который сейчас активно продвигается – все совпадения случайны.

Теги:
Всего голосов 13: ↑11 и ↓2+9
Комментарии5

Кормак Хэйден — владелец Oasis, приложения для iPhone и смартфонов на Android, которое публикует якобы научно обоснованные рейтинги воды и фильтров, опираясь на результаты лабораторных тестов и открытые данные. Плату берут за, как утверждается, доступ к части функций, чтобы финансировать независимые (без рекламы) анализы. На сайте проекта ведётся раздел с рейтингами бутилированной воды и фильтров, поиск по водопроводной воде по городам США, а также возможность заказать домашние тест-наборы для отправки проб в лабораторию.

В личном микроблоге Хэйден опубликовал лаконичный пост. В нём он в три слова и две кавычки пожаловался, что его давно просили сделать приложение для Android, но финансовый результат Кормака разочаровал.

cormachayden_

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

Оплата на Android в Oasis действительно сломана, это так. Однако в регионе США всё работает, указывает Хэйден. Это будет относительно легко пофиксить. Забавно именно то, что поправить уже нельзя: база данных данных Oasis крайне похожа на открытую закраудсорсенную базу данных OpenFoodFacts, а схожие же функции даёт бесплатное приложение Yuka. Кстати, Oasis по дизайну UI сильно напоминает Yuka.

Один из комментаторов даже назвал Oasis всего лишь фронтендом OpenFoodFacts. Кормак парировал, что в данных последней тяжёлых металлов и ПФАС нету и что Oasis собирает и публикует лабораторные данные, а Yuka якобы устарела, часто ошибается и не включает лабораторные измерения. Впрочем, в комментариях спросили, не заполняет ли Oasis эти значения случайными числами. Один из микроблогеров заметил, что на двух скриншотах у бренда Fiji стоит разная оценка.

На самом деле часто данные Oasis вводят в заблуждение. В комментариях к твиту нашли ошибки в выставленных предельно допустимых концентрациях: в приложении часто занижены ПДК относительно рекомендуемых властями США, и в реальности представленные количества вредных веществ представлять угрозу не могут. Зато эта дополнительная строгость к чистоте на три–четыре порядка ниже ПДК позволяет резко критиковать разные бренды за наличие в них мышьяка и тяжёлых металлов.

Хэйден резок в суждениях. В ответ на критику он заявил, что стандарты собеседника в отношении еды и здоровья устарели. Остряки на это заметили, что его Oasis допускает грубые грамматические ошибки уже в описании в каталоге приложений.

Наконец, секретом финансового успеха может быть банальный обман пользователей. Один из комментаторов указывает на тестовый период, который может запутать. Триал длится три дня, а затем начинают списывать по $4,99 в неделю. Возможно, что часть пользователей удаляет приложение и просто забывает отключить эту подписку.

Вызывает вопросы сама цена. Есть ли смысл платить по $30 ежегодной подписки за привилегию сравнивать разные бренды бутилированной воды? И вообще, заслуживает ли статуса отдельного приложения то, что может быть страницей в Интернете?

Теги:
Всего голосов 1: ↑1 и ↓0+2
Комментарии3

Разработчик (Mobile Developer) и программист Алексей Гладков попытался независимо изучить компоненты мессенджера Max.

Теги:
Всего голосов 4: ↑2 и ↓20
Комментарии8

Почему разработчикам опенсорсных приложений для Android может не потребоваться подтверждать свою личность

Недавно Google анонсировала, что скоро смартфоны на базе Android будут работать только с приложениями, чьи разработчики подтвердили свою личность непосредственно Google. Но как это будут проверять? Напрашивается проверка по ключам подписи, но погодите-ка…

Если вы более-менее интересуетесь опенсорсом, наверняка вы слышали про “магазин” F-Droid. Что примечательно в нём — все приложения в его главном (единственном по умолчанию) репозитории собираются из исходников и подписываются одной сущностью — F-Droid. Эта особенность делает данный источник приложений уникальным в своём роде — в Google Play или RuStore каждый разработчик собирает и подписывает приложение сам.

Если Google не передумает и действительно введёт блокировку на “анонимных” разработчиков, вполне возможно, что F-Droid просто создаст единый аккаунт для своего ключа подписи, и продолжит спокойно предоставлять приложения даже на “сертифицированных” Android-девайсах.

Но наверняка вы скажете, что там распространяются приложения, неугодные Google, и будете правы. Однако они и так ломаются каждый месяц самой же корпорацией ввиду открытых исходников этих приложений и способов парсинга контента без официального API. Так что, думаю, обойдётся.

Что думаете?

Теги:
Всего голосов 4: ↑4 и ↓0+7
Комментарии5

🎲 Retrofit 3.0 — что изменилось?

При поддержке блога @dolgo_polo_dev

Вышел Retrofit 3.0. А точнее в один день вышло 2 версии — Retrofit 3.0 и 2.12

Библиотека важная, поэтому попробовал разобраться, что изменилось

Самое интересное случилось в 2.12 — добавили стриминговую сериализацию из Kotlin/Java-классов в Json/Protobuf

Зачем это нужно было?

➡ чтобы большие классы не сериализовывались целиком перед отправкой запроса, а начинали это делать во время передачи данных на бэк

Это позволит чутка снизить нагрузку на процессор и оперативку, если

  • передаете объемные данные в теле запроса (1 мегабайт+)

  • где-то вызываете Retrofit.Call.enqueue() с главного потока — стриминг перенесет сериализацию с главного UI-потока в бэкграунд

Чтобы изменения заработали, нужно создавать конвертер с помощью функции withStreaming()

MoshiConverterFactory.create(moshi).withStreaming() // пример

В Retrofit 3.0 просто апнули версию OkHttp (3.14.9 -> 4.12.0). И немного поправили внутреннего кода, пару строк для совместимости с 4.12.0

Так что если обновите версию Retrofit, у вас транзитивно апнется OkHttp — будьте внимательны, берегите себя и своих тестировщиков

Из хороших новостей — Retrofit 3.0 формальный мажор, то есть бинарно совместим с предыдущими версиями (по словам разработчиков). Мажорное версию апнули для хайпа, чтобы подчеркнуть обновление OkHttp

Пруфы:

остальные посты про Android публикую в https://t.me/dolgo_polo_dev

Теги:
Рейтинг0
Комментарии0

Ближайшие события

Нужно было быстренько перехватить вызов нативной функции и посмотреть значение переменной в Android приложении. Как то давно использовал для этого замечательную утилиту Frida. Установил на планшет frida-server (root уже был) и клиент на PC, написал классический JS хук, но он не работал:

defineHandler({
  onEnter(log, args, state) {
    conslole.log('decoder_CRC_check()');
  },

  onLeave(log, retval, state) {
    const libc = Module.findBaseAddress('libc.so');
    console.log(hexdump(libc, {
      /* address: ptr('0x1000'), -- to override the base address */
      offset: 0,
      length: 64,
      header: true,
      ansi: true
    }));
  }
});

В консоли лишь получал TypeError: not a function at onEnter (D:\Distrib\Android TV\frida\hook.js:7)

Убил полдня в поисках "чего я делаю не так", при том что и официальная дока и нейронки твердят, что именно так и нужно получать базовый адрес модуля и, при необходимости, функций. Оказалось, во Frida 17 автор полностью удалил некоторые функции (а дока и нейронки еще не обновились):

  • Module.ensureInitialized()

  • Module.findBaseAddress()

  • Module.getBaseAddress()

  • Module.findExportByName()

  • Module.getExportByName()

  • Module.findSymbolByName()

  • Module.getSymbolByName()

  • Туда же статические функции Memory

И теперь надо писать цепочку вызовов:

const lib = Process.findModuleByName("libc.so");
console.log("[*] libc.so loaded at base: " + lib.base);
const funcAddr = lib.findExportByName("decoder_CRC_t_init");

Итог получился такой универсальный скрипт:

Java.perform(function () {
	const System = Java.use("java.lang.System");
    const Runtime = Java.use('java.lang.Runtime');
    const SystemLoadLibrary = System.loadLibrary.overload('java.lang.String');
    const VMStack = Java.use('dalvik.system.VMStack');
    // "ожидание"\перехват динамической загрузки нативных библиотек
    SystemLoadLibrary.implementation = function(library) {
		console.log("Loading dynamic library => " + library);
        const loaded = Runtime.getRuntime().loadLibrary0(
            VMStack.getCallingClassLoader(), library
        );
        if (library.includes("mylibname")) {
            console.log("\n[+] Hooked mylibname");
            // перехватываем только нужную нам
            hookNativeFunc();
        }
        return loaded;
    }	
});

function hookNativeFunc() {
    //тут имя полностью как называется сам файл в ресурсах
	const lib = Process.findModuleByName("libmylibname.so");
    console.log("[*] mylibname.so loaded at base: " + lib.base);
    const funcAddr = lib.findExportByName("decoder_CRC_t_init");
    if (!funcAddr) {
        console.log("[-] Function not found!");
		return;
    }
    console.log("[+] Found decoder_CRC_t_init at: " + funcAddr);
    Interceptor.attach(funcAddr, {
        onEnter: function (args) {
            var result = args[0];
            var inputPtr = args[1];
            var len = args[2].toInt32();
            console.log("\n[+] decoder_CRC_t_init called");
            console.log("    result:    " + result);
            console.log("    inputPtr:  " + inputPtr);
            console.log("    len:       " + len);
        },
        onLeave: function (retval) {
            //нужный адрес массива, например из IDA PRO
            const wordArrayOffset = 0x5B2C04;
            const wordArray = lib.base.add(wordArrayOffset);
			var ptr = new NativePointer(wordArray); // современный вариант чтения
            console.log("[*] 5B2C04 contents:");
            try {
                console.log(hexdump(ptr, {
				  offset: 0,
				  length: 512,
				  header: true,
				  ansi: true
				}));
            } catch (e) {
                console.log("[!] Error reading 5B2C04:", e);
            }
            console.log("Return value:", retval);
        }
    });
}

Запускается так frida -U -f com.android.app -l hook.js

Теги:
Всего голосов 5: ↑5 и ↓0+6
Комментарии5

Как ускорить Android-разработку и избавиться от мучительно долгих запусков эмуляторов ради простого теста? 

Ответ — Robolectric — мощный инструмент для UI‑тестирования Android‑кода без эмулятора. 

Позволяет запускать юнит-тесты Android-приложений прямо в JVM, без эмуляторов и физических устройств. Экономия на каждом тестовом прогоне, обратная связь почти мгновенная.

В Android‑комьюнити у Robolectric неоднозначная репутация из‑за трудностей совместимости с другими библиотеками. Но…его почти бесценные возможности пробудили любопытство и желание копнуть глубже и осмыслить этот инструмент. 

Так и родилась статья «Мечтают ли андроиды о Robolectric? Разбираем фреймворк по косточкам» от Павла Нестеренко, нашего Android-разработчика.

Если вы устали ждать, пока эмулятор запустится, и хотите гонять юнит-тесты за секунды прямо в JVM, то рекомендуем статью к прочтению!

Теги:
Рейтинг0
Комментарии0

Save the date: 4 июля встречаемся на Android Meetup!

В программе доклады от спикеров Wildberries & Russ и Альфа-Банка, Q&A-сессия с розыгрышем мерча, нетворкинг и фуршет для классного завершения вечера.

Поговорим о том, как оживить виджеты, подружить Compose с Koin и навигацией, а заодно встроить одно Android-приложение в другое без боли...или с болью:

«Виджеты на Android: это просто?»
Александр Гирев, Android Team Lead продуктовой команды WB Partners

«Compose+Koin+JetpackNavigation: что мы поняли за 2 года»
Арсений Шпилевой, Android-разработчик кор-команды WB Partners

«Интеграция Android-приложений: подходы и лучшие практики»
Абакар Магомедов, главный техлид разработки в Альфа-Банке

Когда: 4 июля 18:00 (сбор гостей с 17:00)
Где: Москва, пространство Весна + онлайн-трансляция

Регистрация уже открыта — присоединяйтесь онлайн или офлайн!

Теги:
Рейтинг0
Комментарии0

Telegram запустил конкурс для разработчиков под Android. Призовой фонд: $50 000. Срок сдачи работ: 11 июля, 23:59 по дубайскому времени (UTC+4). Объявление итогов: июль 2025.

В дополнение к призовым, победитель конкурса сможет присоединиться к команде Telegram в Дубае и зарабатывать 1 миллион долларов в год после вычета налогов.

Задача: Внедрить обновлённый интерфейс профилей в приложение Telegram для Android в строгом соответствии с предоставленным дизайном.

Полные условия конкурсного задания, технические подробности и макеты представлены в отдельном канале платформы.

Теги:
Всего голосов 1: ↑1 и ↓0+1
Комментарии0

Вы - начинающий разработчик под Андроид или просто пишете "для себя" и решили отображать динамическую анимацию через SurfaceView. Например, взяв за основу вот этот код или похожий. Вы разместили SurfaceView или его наследника (у меня MySurfaceView) в activity layout:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activityMain"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <agalilov.doppler.MySurfaceView
        android:id="@+id/dopplerView"
        android:background="#040947"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginBottom="15dp"
        app:layout_constraintBottom_toTopOf="@+id/btnStartStop"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btnStartStop"
        android:layout_width="118dp"
        android:layout_height="56dp"
        android:layout_marginStart="16dp"
        android:layout_marginBottom="16dp"
        android:text="@string/start"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/dopplerView" />

</androidx.constraintlayout.widget.ConstraintLayout>

Запускаете приложение и... ничего не работает: SurfaceView не меняется, картинки нет! Ошибок тоже нет, код рисования выполняется впустую.

Я провёл почти всю ночь, разбираясь в причине. Оказалось, для SurfaceView, который размещён внутри другого View, по-умолчанию используется z-order "позади" родительского View. Это поведение, документированное в разных источниках, оказалось для меня неожиданным.

Лечится просто: при инициализации (в конструкторе класса-наследника) SurfaceView устанавливаем setZOrderOnTop(true):

public MySurfaceView(Context context, AttributeSet attributeSet) {
    super(context, attributeSet);
    setZOrderOnTop(true);
    . . .
}

Вот такая история :)

Теги:
Всего голосов 5: ↑5 и ↓0+7
Комментарии0

URLCheck: Полезная утилита для инспекции URL на Android

Хочу поделиться находкой, которая многим здесь придется по душе. Каждый из нас хоть раз с недоверием кликал по сокращенной или странной ссылке, присланной в мессенджере или почте. Сколько раз мы неосознанно переходили по ссылкам с кучей UTM-меток и прочего трекающего мусора?

Недавно я наткнулся на утилиту для Android, которая решает эту проблему - URLCheck.

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

Вот несколько любопытных ключевых фич:

  • Очистка от трекеров: Автоматически вырезает из линка весь мусор вроде UTM-меток и параметров отслеживания, используя правила проекта ClearURLs.

  • Сканер VirusTotal: Позволяет в один клик отправить ссылку на проверку в VirusTotal и посмотреть отчет. (Нужен свой бесплатный API-ключ).

  • Раскрытие коротких ссылок: Показывает, куда на самом деле ведет укороченный линк типа bit.ly - зачастую фишинговые ссылки скрываются за укороченными линками, чтобы усложнить блокировки.

  • Проверка по хост-листам: Интегрируется со списками StevenBlack (adware, malware, fakenews и т.д.) и предупреждает, если домен находится в одном из них.

  • Pattern-checker: Для продвинутых - можно настроить свои правила на основе регулярных выражений. Например, автоматически заменять http на https или twitter.com на nitter.net.

  • Полный контроль над линком: Вы можете вручную отредактировать URL, посмотреть историю изменений или просто скопировать/поделиться ей.

И самое главное — приложение с открытым исходным кодом! Настоящий швейцарский нож для тех, кто заботится о своей безопасности и приватности в сети.

Где скачать:

В общем, рекомендую попробовать. Для меня это стало одним из приложений категории "must-have".

Теги:
Всего голосов 3: ↑3 и ↓0+4
Комментарии0

Google опубликовала ролик в рамках своей юмористической рекламной кампании Best Phones Forever с «диалогом» между персонифицированными смартфонами Pixel и iPhone. Повествование разворачивается вокруг анонсированных Apple «прорывных» функций iOS 26, которые, по задумке Google, на самом деле уже давно доступны пользователям Pixel.

В видео iPhone перечисляет «новые» возможности операционной системы Apple: перевод сообщений и звонков в режиме реального времени, интеллектуальный отбор вызовов и умное удержание. Выясняется, что аналогичный функционал появился на устройствах Pixel еще пять лет назад, что ставит под сомнение новизну представленных Apple решений.

Теги:
Рейтинг0
Комментарии1

📜 M-V-подставь_свое

Model-View-*** - это шаблоны проектирования
Важное уточнение: это шаблоны проектирования только для presentation слоя, а не для целого приложения

💃 Model
- это как раз та часть приложения о которой мы ближайшее время говорить не будем
Чаще всего ее называют бизнес логикой, но это не совсем верно
Пока, лучше всего воспринимать ее как модель данных которую наше приложение хочет передать пользователю
Причем не важно будет это Ui или API, или что-то другое
MV шаблоны не про frontend, а про то как передать данные клиенту, кем бы он ни был

🖼 View
- это само представление данных пользователю. То, что он по итогу получит
В мире андройд это обычно Activity, Fragment, View или Compose

🪝***
- это какая-то прослойка между моделью данных и их представлением пользователю

Для чего все эти шаблоны вообще придумали?

Дело в том, что View это какой-то вариант отображения данных клиенту 🏐
И часто возникает ситуация, что нужно создать другой вариант отображения ⚽️
Это может быть как бизнес потребность в перекраске кнопок и проведении при этом ab-тестов, 🏀
или желании разработчиков заменить технологию отображения 🏈

Например, у вас было консольное приложение, а вы вдруг захотели сделать для него UI (GitBash|GitUi здравствуйте),
ну или решили заменить Android.View на Compose

Во всех этих случаях нам хочется чем-то разделить саму View и работу с Model, чтобы иметь возможность заменить только View, не трогая ничего другого

В Android, к этому еще добавляется проблема пересоздания View при изменении конфигурации. Когда вы переворачиваете экран (и не только), весь ваш UI просто уничтожается и создается полностью заново. Хотя с точки зрения пользователя это все тот же экран с теми же данными 🫠

Это создает дополнительную потребность отвязать View от остального приложения, чтобы можно было ее подменять прямо в рантайме

Основные шаблоны это MVC, MVP, MVVM и MVI
О них мы и поговорим в следующих постах...

ПС. Посты с большим опережением есть в тг канале из описания профиля

Теги:
Всего голосов 3: ↑2 и ↓1+1
Комментарии1

Магазину приложений RuStore исполнилось три года. Количество установок этого приложения на устройствах пользователей превысило 100 млн.

25 мая 2022 года VK при поддержке Минцифры запустила открытое бета‑тестирование отечественного магазина мобильных приложений для Android под названием RuStore.

В начале февраля 2023 года RuStore объявил о завершении этапа бета‑тестирования магазина приложений. Также создатели платформы перевели интерфейс консоли разработчика на английский язык для удобства иностранных издателей и партнёров.

В декабре 2024 года месячная аудитория магазина приложений RuStore составила 50 млн пользователей старше 12 лет по всей России, согласно исследованию Mediascope. Аудитория Xiaomi Mi Store составила 19 млн, Samsung Galaxy Store — 14 млн, HUAWEI AppGallery — 10 млн, рассказали Хабру в пресс‑службе RuStore. А в Минцифры заявили, что RuStore от VK обошёл по числу пользователей в России App Store от Apple.

В VK добавили, что в каталоге RuStore уже более 50 тысяч приложений, доступных на ОС Android, Harmony OS и «Аврора», от разработчиков из 40 стран мира. Также вышли версии RuStore для электронных книг и умных телевизоров, для проекторов, Hi‑Fi‑аудиоплееров, игровых консолей, кассовых терминалов, умных часов.

Теги:
Всего голосов 6: ↑2 и ↓40
Комментарии9

Google I/O 2025: два вечера главных анонсов вместе с Surf

20 и 21 мая — подключайся к нашим стримам по Google I/O. Будем вместе следить за анонсами новинок, делиться первыми впечатлениями и обсуждать всё самое интересное из мира технологий и разработки в прямом эфире.

Смотрим и комментируем:

  • 20 мая (вторник)
    → 20:00 — Google Keynote: все главные анонсы и будущее технологий от Google.

  • 21 мая (среда)
    → 20:00 — What’s new in Android development tools: новинки для Android-разработчиков.
    → 21:00 — What’s new in Flutter: свежие обновления для Flutter-сообщества.

Время указано по Москве. Позже добавим сюда наших спикеров и персональные ссылки на трансляции.

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

Теги:
Рейтинг0
Комментарии0

Android-приложение «Контакты»: работает — не трогай

У многих полей контакта есть типы. Например, у номеров телефонов или адресов электронной почты по умолчанию есть типы «рабочий» и «домашний». Аналитики сказали, что нужно реализовать дополнительные типы и дать пользователю возможность создавать свои. Звучит легко, но на деле оказалось совсем непросто.

Чтобы заменить стандартные типы полей, нужно добавить новую базу данных с доступными типами полей, а также реализовать отображение и возможность выбора поля. Для этого пришлось во многом переписать код редактирования полей контакта, где и без этого логика была непростой. Теперь стало совсем сложно: при добавлении или обновлении поля в contentProvider нужно указывать тип поля, так что мы начали указывать «custom».

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

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

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

Пришлось опять добавлять костыль: в отдельной корутине ожидать инициализации БД и только потом начинать рисовать экран...

Дмитрий Бражник, старший инженер-программист в департаменте разработки мобильных приложений YADRO, рассказал в статье, как его команда пыталась допилить стандартное AOSP-приложение «Контакты» и к чему они в итоге пришли.

Теги:
Всего голосов 3: ↑2 и ↓1+2
Комментарии0

Хардкодить допоздна? А может, лучше нет, ворк?

>> Регистрация и программа <<

23 апреля в 20:00 приглашаем воронежских разработчиков на неформальный митап. Для тех, кто не сможет прийти офлайн, будет трансляция.

Никаких скриншотов кода на слайдах. Никакого душного обсуждения документации. Поговорим о том, что окружает нас вне работы. Прокачаем софт-скиллы и нетворкинг.

В программе митапа три доклада:

  • Лёша, Android-разработчик Surf — «Дедлайн "вчера": как работать с приоритетами».

    Как рассеивается внимание? Как ставить приоритеты в работе с командой? Когда нужно выносить переписку в звонок, а когда можно обойтись текстом? Ответим на эти и многие другие вопросы про приоритеты в работе и жизни.

  • Дима, Flutter-разработчик Surf — «Тимлид — друг или враг? Или так»?

    Расскажу о роли тимлида, но со стороны нижестоящего сотрудника. Что мне нравится/что не нравится в лиде, что для меня кажется полезным, а смысл чего я не понимаю.

  • Кирилл, iOS-разработчик, наш друг и гость из Una Financial — «Work-life health для IT-шника среднего возраста».

    Поделюсь жизненными проблемами разработчиков и способами их решения. Внимательный слушатель вообще сможет их избежать! Обсудим, как сделать жизнь лучше, повысить её качество. Максимально продлим трудоспособный возраст.

Митап пройдет 23 апреля, в 20:00, в воронежском пространстве «Eventuki»: ул. Фридриха Энгельса, 52.

Участие в митапе бесплатное, чтобы прийти или получить ссылку на трансляцию, нужно зарегистрироваться 👈

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

Теги:
Рейтинг0
Комментарии0

Вышло видеоруководство по переводу смартфонов Pixel на GrapheneOS с упором на конфиденциальность, включая настройку ключевых параметров и установку приложений, а также способы работать с сервисами Google Play с отключением трекеров.

Теги:
Всего голосов 3: ↑1 и ↓2+1
Комментарии1

Добавлен Room! :)
Ранее я уже делился статьей про Delight SQL Viewer — библиотеку, позволяющую отлаживать SQLDelight-базу данных напрямую внутри вашего Kotlin Multiplatform-приложения. Однако в одном из наших внутренних проектов используется Room Multiplatform и хотелось иметь возможность отладки БД и в нем. Так и появилась вторая версия библиотеки, которая теперь поддерживает и Room, и SQLDelight.

Что делает библиотека?

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

  • Автоматически добавляет иконку-ярлык для быстрого запуска (Android и iOS).

  • На Desktop ярлыки не поддерживаются. Для запуска интерфейса используйте обычную кнопку или меню в вашем UI.

  • Легко отключается в продакшен-сборках — можно либо не вызывать init, либо подключать stub-модуль вместо основной библиотеки.

Как использовать?

Зависимости (shared/build.gradle.kts)

val isRelease = /* Ваша логика определения релизной сборки */

dependencies {
    if (isRelease) {
        // В релизе – stub, чтобы не вшивать весь отладочный UI.
        api("ru.bartwell.delightsqlviewer:stub:2.0.0")
    } else {
        // В debug – полная функциональность.
        api("ru.bartwell.delightsqlviewer:runtime:2.0.0")
        api("ru.bartwell.delightsqlviewer:core:2.0.0")
        // Выберите, что используете:
        api("ru.bartwell.delightsqlviewer:sqldelight-adapter:2.0.0")
        // или
        // api("ru.bartwell.delightsqlviewer:room-adapter:2.0.0")
    }
}

Инициализация

  • SQLDelight (Android):

    DelightSqlViewer.init(
        object : SqlDelightEnvironmentProvider() {
            override fun getDriver() = sqlDelightDriver
            override fun getContext() = context
        }
    )
  • Room (Android):

    DelightSqlViewer.init(
        object : RoomEnvironmentProvider() {
            override fun getDriver() = roomDatabase
            override fun getContext() = context
        }
    )
  • iOS (пример для SQLDelight):

    let provider = SqlDelightEnvironmentProvider(driver: sqlDriver)
    DelightSqlViewer.shared.doInit(provider: provider, isShortcutEnabled: true)

    Аналогично и для RoomEnvironmentProvider.

    Также, чтобы ярлык корректно работал на iOS, в вашем AppDelegate нужно переопределить методы обработки ярлыков, например:

    class AppDelegate: NSObject, UIApplicationDelegate {
        func application(
            _ application: UIApplication,
            configurationForConnecting connectingSceneSession: UISceneSession,
            options: UIScene.ConnectionOptions
        ) -> UISceneConfiguration {
            return ShortcutActionHandler.shared.getConfiguration(session: connectingSceneSession)
        }
    }

    Или вызовите DelightSqlViewer.shared.launch() в обработчике вашего Shortcut.

  • Desktop:

    DelightSqlViewer.init(
        object : SqlDelightEnvironmentProvider() {
            override fun getDriver() = sqlDelightDriver
        }
    )

Аналогично и для RoomEnvironmentProvider.

Запуск

После инициализации вызов DelightSqlViewer.launch() откроет интерфейс просмотра и редактирования (на Android/iOS можно также запустить через ярлык при долгом тапе на иконку приложения).

Button(onClick = { DelightSqlViewer.launch() }) {
    Text("Open DB Viewer")
}

Итог

Теперь Delight SQL Viewer покрывает оба основных способа хранения данных в мультиплатформенных проектах — SQLDelight и Room Multiplatform. Если нужно быстро проверить содержимое вашей БД или вручную поправить что-то прямо во время тестирования, эта библиотека может сэкономить кучу времени. Ну и, конечно, легко «прячется» в релизе, чтобы никакого отладочного UI не оставалось.

Ссылка на репозиторий: https://github.com/bartwell/delight-sql-viewer

Буду рад фидбэку и вопросам!

Теги:
Всего голосов 1: ↑1 и ↓0+3
Комментарии0

Как устроена мобильная архитектура Авито?

Гость нового выпуска подкаста «Android Broadcast»Александр Бильчук, руководитель юнита мобильной архитектуры Авито. В беседе с Кириллом Розовым Саша делится особенностями работы отдела мобильной архитектуры:

  • как ставятся задачи и требования к их выполнению?

  • как оценить пользу архитектурных решений?

  • как влияют Jetpack Compose, SwiftUI, AI на архитектуру?

  • как вообще прийти к роли мобильного архитектора?

Ответы на эти и другие вопросы вы найдете в видео.

Подписывайтесь на канал AvitoTech в Telegram, там мы рассказываем больше о профессиональном опыте наших инженеров, проектах и работе в Авито, а также анонсируем митапы и статьи.

Теги:
Всего голосов 15: ↑15 и ↓0+17
Комментарии0

Aptoide криво публикует приложения в RuStore

Это перевод с английского языка. В русской версии описания было "обновление не затрагивает РФ"

В общем, мало что сделали это (стащили в свой стор и перезалили в рушку) без разрешения, так еще и криво.

Теги:
Всего голосов 2: ↑0 и ↓2-2
Комментарии0

Сегодня мое приложение "Печать чека НПД" стало "кирпичом". Что случилось ? Налоговая сделала метод апи требующим авторизацию.

https://lknpd.nalog.ru/api/v1/receipt/nomer_inn/id_cheka/json

Вы спросите, так как какая проблема добавить к запросу авторизацию ?

1) Документации на апи нет

2) Проблемы пройти модерацию Google Play после такой доделки

а) Что отвечать на вопрос об афилированности с госорганами. В обоих вариантах чувствую тот еще гиморой

б) Секция персональных данных. Угу. Попробуй ИИ объяснить зачем тебе логин/пароль от чужого сайта

Теги:
Всего голосов 1: ↑1 и ↓0+1
Комментарии3

Как сократить JSON на 74% при 100 элементах?

Важное преимущество SDUI — возможность внедрять изменения без выпуска новых версий приложений. Но это же преимущество есть его недостаток, ведь передача всех данных по сети зависит от качества соединения и увеличивает объём данных. 

Качество связи мы не можем контролировать, а вот уменьшить количество передаваемой информации посредством сокращения JSON, — вполне.

Нам нужна функция, которая могла бы вынести и переиспользовать общую логику. В нашем SDUI уже существует концепция «функций», и их разнообразные реализации, но ни одна из них не умела сокращать JSON, поэтому нужна была новая.

Функция должна брать общую часть и заменять в ней только те части, которые отличаются от элемента к элементу, оставляя остальное неизменным. Подобный подход давно применяется в виде шаблонизации, что и было необходимо реализовать. Идея в том, чтобы взять шаблон и подставлять в него различные значения. В нашем SDUI мы уже умели подставлять значения из других мест, и для этого у нас есть собственный синтаксис.

Детали реализации шаблонизации в статье.

Теги:
Всего голосов 1: ↑1 и ↓0+1
Комментарии0

Обнаружены проблемы с отображением Flutter приложений на Snapdragon 8.

https://github.com/flutter/flutter/issues/137002

Проблемы касаются тех приложений, которые используют Impeller (новый графический движок, который пришёл на замену Skia), при его отключении всё становится хорошо.
Проблемы замечены на Samsung Galaxy S22+, Redmagic 10, Honor Magic6 Lite 5G и Honor Porshe Design Magic7 PSR. На всех этих устройствах установлен Snapdragon 8.

Пример глитча:

Теги:
Рейтинг0
Комментарии2

Kotlin Multiplatform на практике: как работать с технологией (видео-туториал)

Выпустили серию видео о базовых аспектах работы с Kotlin Multiplatform, технологией для мультиплатформенной разработки (iOS, Android, Web, Desktop).

KMP позволяет использовать общую кодовую базу для нескольких платформ. Причём мы можем гибко регулировать, какую часть кода делаем общей (например, оставляем нативный UI-слой, а бизнес-логику делаем общей).

Рассказали, как и для чего применять технологию на практике, и как к ней подступиться.

Уже доступны все шесть выпусков туториала:

1. Что из себя представляет технология KMP?

2. Настройка окружения

3. Структура проекта

4. Верстка на SwiftUI

5. Верстка на Compose

6. Сетевой слой

Посмотреть туториал можно здесь:

К каждому выпуску приложен документ с пояснением некоторых терминов и полезными ссылками (см. в описании видео), которые пригодятся при ознакомлении с материалом.

Теги:
Всего голосов 9: ↑9 и ↓0+9
Комментарии0

Привет, друзья! Меня зовут Александр Минкин, в компании SM Lab я работаю тимлидом Android-разработки на продукте МП Спортмастер. Сегодня я хочу поделиться с вами подробностями об одном из самых мощных архитектурных паттернов для мобильных приложений - MVI (Model-View-Intent). Этот паттерн помогает создавать приложения с четко разделенной логикой, улучшенной тестируемостью и высокой масштабируемостью. Давайте разберемся в его особенностях и посмотрим примеры кода на языке программирования Kotlin в Android с использованием Kotlin Coroutines, StateFlow и Fragment, а также давайте расширим наш пример с использованием чистой архитектуры, где добавим уровни domain-слоя (UseCases) и data-слоя (Repository). Этот подход поможет вам управлять состояниями приложения более эффективно и реагировать на изменения в реальном времени.

 Основные компоненты MVI с чистой архитектурой:

1. Model: Хранит состояние приложения.

2. View: Отображает текущее состояние Model.

3. Intent: Интерпретирует действия пользователя и направляет их в UseCase.

4. UseCase: Содержит бизнес-логику и выполняет операции.

5. Repository: Обеспечивает доступ к данным, будь то локальные или удаленные источники.

Преимущества MVI:

- Однозначное управление состоянием: Все состояния приложения проходят через один поток данных, что упрощает их отслеживание.

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

- Тестируемость: Изолированные компоненты упрощают написание тестов.

Давайте рассмотрим пример использования MVI в приложении на Kotlin. Допустим, у нас есть приложение для управления задачами. Ссылка на gist:

https://gist.github.com/Rasalexman/53f9be0fc4e295b987e0921839a9a84e

Здесь мы рассмотрели базовый пример использования MVI. Хочу отметить, что в разных реализациях этот архитектурный паттерн, может включать в себя несколько дополнительных компонентов, таких как Reducer - это компонент помогающий преобразовать входное намерение в состояние. В примере выше таким reducer может выступать функция `processIntent`, но чаще его делают как абстракцию в виде интерфейса с функцией reduce, которая принимает Intent и возвращает State. Также мы можем добавить такой компонент как Store - это общая часть для работы с намерениями, которая получает результат обработки намерения и может производить как SideEffects, так и само состояние (State) экрана. Количество компонентов может меняться от сложности реализации, вплоть до добавления специальных объектов middleware и сайд-эффектов (SideEffects). Подробное рассмотрение данных компонентов не входило в текущую статью. С более сложными реализациями вы можете ознакомиться по ссылкам ниже

Заключение:

MVI - это мощный архитектурный паттерн, который помогает разрабатывать структурированные, масштабируемые и легко тестируемые приложения. Его использование позволяет разработчикам четко разделять логику представления, состояния и намерений пользователя, упрощая сопровождение и расширение приложения.

Использование Kotlin Coroutines и StateFlow с архитектурой MVI позволяет вам эффективно управлять состояниями и асинхронными операциями в вашем приложении. Интеграция чистой архитектуры с использованием UseCases и Repository делает ваше приложение более модульным и легко масштабируемым. Это упрощает написание кода, при этом ваше приложение становится более отзывчивым и масштабируемым, а так же удобным в управлении данными и бизнес-логикой, улучшая тестируемость и поддержку кода.

Спасибо, что прочитали данную статью. Буду признателен за комментарии и реакции к этому посту. Делить какую реализацию MVI вы используете у себя в проектах. Всем отличного настроения, помните, что его, как и архитектуру, вы можете выбирать сами ;)

Теги:
Всего голосов 2: ↑1 и ↓10
Комментарии0

Всем доброго дня. Представьте, что есть система, которая автоматически генерирует технические спецификации и документацию для разработчиков на основе описания проекта.

Фичи:

Генерация структурированных документов в Markdown/PDF

Интеграция c Jira/Confluence

Возможность автоматической генерации диаграмм (ERD, Sequence)

Полезно ли это/пользовались бы сами?

Теги:
Всего голосов 3: ↑3 и ↓0+4
Комментарии2

Пишем приложение для поиска объектов на С++ (а не на Python)

Результат работы приложения по поиску объектов на С++
Результат работы приложения по поиску объектов на С++

Приложения по поиску объектов, написанные на С++, работают ничуть не хуже привычных вариантов на Python. На это есть несколько причин:

  • Программы на С++ получаются более быстрыми и компактными. Инженерам доступно больше вычислительных ресурсов, так как современные компиляторы оптимизируют программу в соответствии с архитектурой целевого процессора.

  • C++ не использует дополнительный сборщик мусора для управления памятью — это существенно влияет на производительность программы. 

  • Размер программы также можно уменьшить, поскольку C++ не использует дополнительную виртуальную машину и компилируется непосредственно в машинный код.

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

Если хотите написать такое приложение, изучите материалы инженера YADRO и ML-энтузиаста Кирилла Колодяжного. Он подробно описал, как реализовать программу на С++ с применением библиотек компьютерного зрения.

Подготовительная часть →

Практическая часть →

Теги:
Всего голосов 6: ↑6 и ↓0+8
Комментарии0

Google Play с 26 декабря 2024 года приостанавливает на неопределенный срок проведение платежей за приложения разработчикам с банковскими счетами, зарегистрированными в России.

В марте 2022 года Google отключил показ рекламы в России, а позже прекратила монетизацию просмотров на YouTube для российских пользователей на YouTube. Это не затронуло аудиторию из других стран. В мае того же года компания запретила российским разработчикам загружать и обновлять платные приложения в Google Play, что лишило их возможности монетизации в России.

Теги:
Всего голосов 6: ↑4 и ↓2+3
Комментарии1

Да кто такой этот ваш билд-инженер?

Гость нового выпуска Android BroadcastСергей Боиштян, Android-инженер в Авито. Сергей обсуждает профессию билд-инженера с ведущим подкаста Кириллом Розовым. Вот про что говорят:

  • с какими задачами приходится сталкиваться в практике;

  • какой прогресс достигнут в Gradle и Android Gradle;

  • какое будущее нас ждёт в сборках Android и Kotlin Multiplatform-проектах.

Сергей знает, о чем говорит, ведь он из команды Speed: эти ребята у нас занимаются developer experience для Android-разработчиков Авито. Проще говоря — позволяют нашим инженерам сфокусироваться на написании фичей, пока такие богатыри, как Сергей, разбираются с версионированием, библиотеками и прочими штуками.

В подкасте Сергей рассказывает про жизнь билд-инженров, их задачи и историю — откуда они вообще взялись и как эволюционировали до актуального состояния. Настоятельно рекомендуем послушать!

Подписывайтесь на канал AvitoTech в Telegram, там мы рассказываем больше о профессиональном опыте наших инженеров, проектах и работе в Авито, а также анонсируем митапы и статьи.

Теги:
Всего голосов 17: ↑17 и ↓0+17
Комментарии0

Согласно данным, технология PWA стала популярнее среди мессенджеров, банков, интернет-магазинов и других видов компаний.

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

1. Устанавливаются в обход сторов.

Пользователи скачивают прогрессивные веб-приложения напрямую из браузера с сайта компании. Это помогает компании сэкономить бюджет на продвижение приложения в сторах.

2. Работают в офлайн-режиме.

Прогрессивные приложения может работать в автономном режиме без соединения с сервером.

3. Загружаются за секунду. 

PWA загружаются очень быстро благодаря HTML-отдаче. С момента загрузки до появления первого элемента или изображения обычно проходит не более 1 секунды.

4. Весит меньше мегабайта. 

В отличие от нативных приложений PWA занимает менее 1 Мб в памяти смартфона. 

5. Эффективно адаптируется под устройство. 

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

6. Выглядит привычно для пользователя. 

При загрузке PWA пользователь может установить ярлык или иконку приложения на экран смартфона.

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

Теги:
Рейтинг0
Комментарии0

Всем привет! Сегодня поговорим о PWA.

Прогрессивное веб-приложение (PWA) — это гибрид обычной веб-страницы и мобильного приложения. Оно сочетает в себе функции большинства современных браузеров с преимуществами мобильных приложений и создаётся с использованием стандартных веб-технологий, включая HTML, CSS и JavaScript.

Функциональные возможности включают работу в автономном режимеpush-уведомления и доступ к аппаратуре, что создает аналогичный нативным приложениям опыт работы для пользователя.

Некоторые из крупнейших в мире компаний, такие как Twitter, Instagram, Uber, Pinterest, Forbes, Alibaba и другие, уже используют PWA.

Согласно сообщению из CNBC, к 2025 году почти три четверти населения мира будут использовать для доступа к интернету только смартфоны. Поэтому, если вы планируете создать новый веб-сайт или редизайнить старый, вам следует задуматься о создании PWA.

Теги:
Всего голосов 5: ↑1 и ↓4-3
Комментарии8