Dolgo.polo Dev | Денис Долгополов
2.22K subscribers
96 photos
2 videos
128 links
Разбираемся в мобильной разработке (Android/iOS) и пытаемся выяснить, зачем оно так устроено

Статистика/цены: @dolgo_polo_dev_stats

По вопросам/рекламе: @dolgopolovdenis
Download Telegram
☁️Оффлайн-встречи мобильных разработчиков уже в эти выходные!

😉Привет! На связи Coffee&Code — международное сообщество мобильных разработчиков.

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

🤪Пообщаемся на технические темы, обсудим интересные события из мобильной разработки, разберем вопросы с собеседований и поделимся опытом!

🤖 Android | 📱 Mobile | 🍏 iOS

📍СПИСОК ГОРОДОВ

💃Также мы выкладываем интересные технические/полезные видосики в наш YouTube канал и записываем Подкаст! Ждем тебя на встречах!
🔥7👍53👏2😍2
🪩 митап

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

поговорю про подводные камни в проектировании API для SDK, о проблемах ABI и мажорных каскадных релизах 😵

также там будут крутые доклады коллег, слайды с картинками и кейтеринг -> подробности и регистрация

@dolgo_polo_dev
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥22👍7🌭43
🧬 Запрещенка в хэдерах

У каждого http-запроса и ответа есть заголовки (они же headers, они же мапка ключ-значений)

Но есть нюанс, о котором почему-то не написано красными большими буквами во всех гайдах по Retrofit/OkHttp


⚠️ не все символы можно класть в хэдеры (и cookie)


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


Актуальный список разрешенных символов можно найти в коде:

🔵okhttp3.Headers.checkValue()
🔵okhttp3.Headers.checkName()

сейчас это:

🔵для ключей: c in '\u0021'..'\u007e'
🔵для значений: c == '\t' || c in '\u0020'..'\u007e'

Например, в хэдере нельзя передавать знак рубля ₽ или иконки гендеров ♂♀ 🤬

@dolgo_polo_dev
Please open Telegram to view this post
VIEW IN TELEGRAM
24🔥5🥴3
😮 Топ вещей, которые нужны не всем

Топ #1 — минимально поддерживаемая версия приложения 🥇

Под каким предлогом это затащили вообще во все приложения? 🤯


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

А вместо QR-кода вижу

"СРОЧНО! срочно! обнови приложение или тебя ждет 10 лет неудач!"


и встаю перед выбором:

🔵застопорить очередь на 10 минут, пока обновляю приложение на несчастном 2G, который еле ловит за толстыми стенами магазина

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


➡️ Кому нужна минимально поддерживаемая версия?

Приложениям, которые часто меняют/дополняют свой основной функционал. Например, к Яндекс.Картам или Телеграмму в этом плане ноль претензий


➡️ Помогает ли автообновление приложений?

Нет, ведь если не открывать приложение какое-то время, оно перестает автообновляться и архивируется


➡️ Компромисс

Если у вашего приложения 1-2 основные функции (например, показать штрихкод!), то не обязательно мучать пользователей принудительными обновлениями. Думаю, лояльность пользователей важнее time to market минорных фичей

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

@dolgo_polo_dev
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥28👍13❤‍🔥3
#рекомендация

Есть такой канал про пока еще мобильную разработку – Everlasting Loops

В нём можно встретить как популярные вопросы с собеседований, так и неочевидные инсайты, особенности IDE-шного тулинга, контрибьют в Kotlin (ну… как-нибудь), или же просто фан-факты

А также почему ломается Unity, зачем котлину public и чего можно ожидать от лямбды

И сначала думаешь, что вроде бы шаришь, а потом хоп – и вот ты уже гуглишь, что это за guards

Если crossinline уже выучил
🔥9👍5🦄4🫡1
🧬 Стих

Осторожно, кринж 😳

Попросил нейросеть написать стих про Android-разработчика. Она выполнила задание с первого раза:


Fragment-осколки в ViewModel-реке,
LiveData танцует в Lifecycle-ручье.
Jetpack-крылами взлетает за грань,
Где Room хранит секреты, как древний талисман.

Dagger-остротой разрезает тьму,
Coroutines плетут асинхронную мглу.
RecyclerView — его ритмы-маски,
А в Stacktrace — тайный шифр Пизанской башни.

ANR-демоны грызут тишину,
Но Proguard-магия стирает войну.
CI/CD — его алхимия в бойне,
Чтоб APK стал цифровой иконой.

Flutter-соперник? Не страшен мираж —
Compose-канвасом он рисует пейзаж.
API-бездны покоряет в прыжке,
Где Firebase звёзды горят на песне.

Его Git-хроники — вечный полёт,
Где Merge Conflict — лишь тень на восход.
Android-магнат, в его коде — эпоха,
Сквозь NullPointer — к звёздам прорвётся вздох! 🚀

@dolgo_polo_dev
Please open Telegram to view this post
VIEW IN TELEGRAM
👏25😁14🗿8🔥4💊4
🐌 Чек-лист замера перфа

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

🐌 Запуск приложения
🔵отдельный вопрос — откуда до куда мерить запуск, тут есть простор для творчества
🔵как минимум надо мерить Application.onCreate() и инициализацию библиотек

🐌 Открытие нового экрана
🔵момент от нажатия пользователем кнопки до отрисовки первого полезного UI-элемента
🔵часто включает в себя сетевой запрос на бэк — довольно рандомная по времени вещь
🔵желательно разбить эту метрику на подэтапы

🐌 Скорость сетевых запросов на бэк
🔵подготовка запроса и обработка респонса
🔵установка соединения (DNS/TCP/TLS)
🔵время отправки/чтения байтов по интернету
🔵время работы бэка (когда запрос уже отправлен, но ответ еще не начал считываться)
🔵загруженность установленных соединений (не пора ли увеличить connectionPool)
🔵процент попадания в кэш
🔵процент успешных запросов к упавшим
🔵размеры запросов

🐌 FPS — количество кадров, которые успевают отрисоваться в секунду
🔵интересны места, где идет просадка FPS

🐌 Видео-контент
🔵скорость отрисовки первого кадра
🔵процент подвисаний
🔵скорость загрузки чанков
🔵все вышеперечисленное для разных форматов и битрейтов

🐌 Картинки
🔵всё, как и для обычных сетевых запросов, но с разбиением по cdn-ам и форматам изображений

Еще что-то забыл?

@dolgo_polo_dev
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1512
✂️ trim()

Функция String.trim() вырезает пробелы в начале и в конце строки:

" а " -> "a"

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


Последняя нервная клетка умирает, когда вбиваешь в поиск гитлаба название ветки, а её там нет

И только после микроинсульта понимаешь, что это из-за лишнего пробела в названии " epic/123"


Или ищешь печеньки 🍪 в онлайн-магазине, а " печеньки" там нет, есть только "печеньки"

Или логинишься с помощью логина и пароля, а для аккаунта "терминатор6200 " почему-то логин не найден

@dolgo_polo_dev
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥19😁15👍4❤‍🔥2🍌2
😄 Очепятка в стандарте

referer — стандартный хэдер для http-запросов

он показывает, откуда пользователь попал на страницу/в приложение

например, referer = google.com ознаечает, что пользователь попал на сайт/в приложение из гугла. полезная штука для аналитики


но забавно другое — слова referer не существует, правильное написание — referrer (с двумя rr)

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


например, Cronet (сетевой клиент от гугла для Android, iOS и не только) тупо вырезает хэдер referer 🧠 из запроса. При этом referrer спокойно дает отправить

@dolgo_polo_dev
Please open Telegram to view this post
VIEW IN TELEGRAM
😁22👍8🤯7❤‍🔥1🤣1
🔓 Почему нельзя подключаться к публичным Wi-Fi в Макдональдсе?


С дества слышал, что подключаться к общественным Wi-Fi небезопасно. И это утверждение у меня никогда не билось с фактом "https трафик зашифрован, ведь s — это security" (ну или TLS/SSL)

Если весь трафик зашифрован умными алгоритмами, то какая-разница, через какие радиоволны подключаюсь к бэку? 🤯


Разгадка нашлась простая — проблема в атаке man in the middle (мужик в середине)


Это не какая-то конкретная уязвимость, а весь спрект потенциальных проблем

Имея доступ к роутеру, то есть находясь посередине между приложением и бэком, злоумышленник может попытаться:

🔵подменить DNS -> подменить итоговый IP сайта
🔵понизить соединение с https до http
🔵средиректить на произвольный url
🔵подменить публичный ключ шифрования (сертификат)


Естественно, все не так просто, и на произвольном сайте такое злодей не провернет. Нужно целое стечение обстоятельств, несколько допущенных дыр, чтобы любая из атак стала возможной. Но доступ к Wi-Fi, через который устанавливается соединение, повышает шанс этой атакой воспользоваться, ведь трафик льется через роутер как через прокси


А дальше начинается самое интересное — центры сертификации, разные версии SSL, шифрование трафика через VPN, дополнильные проверки IP браузером — огромный мир борьбы с мужиком в центре


Кстати проблема man in the middle справедлива и для мобильных приложений — существует не так уж много способов безопасно передать информацию между двумя приложеними, не дав кому-то посередине ее перехватить

@dolgo_polo_dev
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥13🦄9👍52🤡2❤‍🔥1😎1
TLS / SSL / SSL Pinning / mTLS на пальцах

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



Первый запрос к бэку всегда особенный — на нем устанавливается соединение и происходит обмен информацией для шифрования трафика

TLS / SSL — протоколы шифрования
SSL — старый
TLS — новый (самая крутая версия 1.3)

Один из этапов шифрование — передача публичного ключа шифрования вместе с сертификатом

💡 Сертификат — это файлик с уникальным публичным ключем, который владелец домена (например, ya.ru) получает от центра сертификации

💡 Центр сертификации — организация, которая выдает сертификаты доменам и потом проверяет их


Так вот, бэк передает свой сертификат на мобилку. Мобилка идет к центру сертификации и спрашивает:

Точно ли этот сертификат принадлежит этому домену?


Если все ок, то с помощью этого сертификата трафик шифруется

➡️ стороннее лицо (центр сертификации) подтверждает, что мы общаемся напрямую с ya.ru

Это и есть SSL / TLS (если сильно упрощать)

продолжение
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥19🌭2😎1
SSL Pinning

Помните про мужика в середине?

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


Чтобы этого избежать, мы можем не передавать сертификат в момент установки соединения, а заранее зашить его в код мобилки

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

В этой схеме приложение само является центром сертификации, так как само проверяет сертификат



🔵спасаем пользователей, которые отключили проверку сертификатов на устройстве, не понимая, чем рискуют


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


mTLS

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

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

Если мобилка не отправила сертификат или отправила неверный — бэк не станет устанавливать соединение


🔵защищаем бэк от DDOS, даем ему возможность игнорировать запросы без сертификата


🔵добавляется еще один шаг при установке соединения -> может негативно сказаться на скорости сетевых запросов (тратим дополнительные миллисекунды)

первая часть поста
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥22👍5😎2🌚1
Короткий топ технологий


гибкость 👇

🔵низкоуровневая разработка
🔵нативная разработка
🔵кросс-платформа
🔵AI-вайб-кодинг
🔵AI+вайб-кодинг
🔵no-code
🔵шаблоны
🔵нам IT-отдел не нужон, а логотип дочка нарисует

time to market 👆


@dolgo_polo_dev
Please open Telegram to view this post
VIEW IN TELEGRAM
🏆21😁17🤡4
🐦‍⬛️ Как передать секрет между приложениями безопасно

Помните про мужика в середине?

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


💡 Например, пользователь поставил смешную фотку на аватарку в нашем приложении, и мы хотим по-секрету рассказать об этом всем дружеским приложениям так, чтобы об этом не узнали чужие


⚠️ Какие варианты точно не подходят:

🔵Intent — любое приложение может перехватить Intent, зарегистрировав intent-filter в Manifest

🔵Explicit Intent — это тот же самый Intent, но с явным указанием пакета/класса, которому он отправляется. На устройстве не может быть двух приложений с одинаковым пакетом. Но на устройстве могут быть хакнутые сборки с оригинальным пакетом, сливающие данные, которые пользователь скачал не из Play Market, а с пиратского сайта

🔵deeplink с query-параметрами — любое приложение может перехватить deeplink, зарегистрировав его в Manifest

🔵общий зашифрованный файл — любой алгоритм шифрования и ключи шифрования, зашитые в apk, вычисляются за пару минут. так что сколько не шифруй, все-равно зареверсинжинирят



🗝 Более интересные варианты:

🔵AccountManager и ContentProvider / BroadcastReceiver с protectionLevel = "signature" и KeyStore — позволяют безопасно общаться приложениям с одинаковой подписью

🔵App-links — подходят, если нужно передать какой-то секрет из браузера в мобильное приложение. Благодаря этой технологии домен сайта связан с подписью приложения

🔵Доверенное лицо — это любые сторонние сервисы-посредники, который мы почему-то решили доверять (свой бэкенд, гугл аккаунт и т.д.)

@dolgo_polo_dev
Please open Telegram to view this post
VIEW IN TELEGRAM
1🔥234🍓43
🍏 Эко-френдли код

Почему какое-то приложение жрет батарейку больше остальных?

Потому что там много анимаций, а в бэкграунде запускается майнер? Возможно, но есть более физическое объяснение


💡 Например, сетевые запросы напрямую влияют на расход батареи

Чтобы выполнить запрос к бэку, нужно вывести Wi-Fi-модуль из сна ➡️ подать на него напряжение ➡️ сначала отправить байты в интернет с помощью излучения радиоволн ➡️ повисеть какое-то время в режиме ожидания ответных радиоволн

То же самое с Bluetooth/NFC/динамиками/датчиками — для передачи информации нужно потратить энергию


При этом теоретически важно не только количество передаваемой информации в физический мир, но и частота

Например, энергоэффективнее отправить 10 запросов в бэкенд параллельно, чем последовательно — ведь так мы быстрее позволим Wi-Fi платке вернуться в режим сна


Но в реальном мире такими микрооптимизациями занимается в лучшем случае ОС или драйвер, нам же достаточно описать, откуда и куда перекладывать джейсончики

@dolgo_polo_dev
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥12🍓10👍1
🖥 Будущее офисных компов у меня на столе

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

Задачи у него такие:

минимальный размер, так как
а) это эстетично
б) это практично — иногда кидаю его с собой в портфель в поездки, весит чуть больше блока питания от ноутбука
в) удобно с подъемным столом — не нужно ничего придумывать, просто положил под монитор

красивое — есть аналоги чуть мощнее за ту же цену, но в пластмассовых стремных коробках

тянет без лагов среднего размера проекты в AutoCAD, Matlab, Android Studio, Figma

можно позапускать на средних в 60фпс всякие простенькие игры — Dont Starve Together, Party Animals, Raft, Split Fiction...

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


Со всеми этими задачами отлично справляется встроенка AMD 680M — не шумит, не греется выше нормы, не фризит

Если вы геймер, то судя по тестам из интернетов можно взять MacMini на M4 за 70-80к и комфортно играть на нем даже в киберпанк


Итого — все мои потребности закрыл на 5️⃣. Через пару лет этот оставлю под медиастанцию, а для остального возьму что-нибудь с еще более мощной встроенкой


Думаю, со временем все не_игровые пк перейдут в такой формат. Коробки размером с пылесос больше не имеют смысла, но пока они чуть дешевле


А в идеальном мире домашние компы заменят телефоны, которые с помощью внешнего монитора и type-c будут превращаться в полноценный пк. Надеюсь, лет через 5-10 мы окажемся в этой точке 🌈


Минусы и характеристики моей коробки скину в комменты👇

@dolgo_polo_dev
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥13👍8
🦙 Почему первые 300мс жизни сложнее всего?

Пользователь нажимает на иконку

И тут начинается треш и угар — в ближайшие 300мс случится больше интересного, чем в фильмах Marvel за последние 5 лет


Пошло поехало:

🔵проинициализоровать часть DI

🔵проинициализировать большую часть библиотек в нужном порядке

🔵стянуть и применить фича-флаги, на которых будет работать приложение

🔵собрать начальный стейт для первого экрана в зависимости от десятков параметров (авторизован ли юзер? какой язык выбран?...)

🔵прочитать кучу локальных данных из долгого ПЗУ, чтобы дальше работать с быстрой ОЗУ

🔵установить соединение с бэком (сходить в DNS, пройти этапы коннекта по TCP/TLS)

🔵выбрать CDN для загрузки медиа-контента

🔵проверить, есть ли в кэше информация для отображения

🔵если нет, начать грузить новую с бэка

🔵отрисовать какой-нибудь скелетон UI

🔵запустить префетч и прогрев важных экранов

🔵замерить все предыдущие этапы, отправить информацию о перфе в аналитику


фух, кончили. наконец-то можно вывести "Ваше приложение устарело, пожалуйста, обновите версию"

@dolgo_polo_dev
Please open Telegram to view this post
VIEW IN TELEGRAM
😁576👍4😱4
#рекомендация

@mobile_appsec_world — один из крупнейших каналов про безопасность мобильных приложений

если вдруг не подписаны, то вот что вы пропускаете:

🔵Как отключить SSL Pinning для дебага?

🔵Новости про использование AI в реверс-инжиниринге

🔵Анонсы конференций и вебинаров про мобильное ИБ

🔵Ссылки на полезные тулзы для анализа apk

и все это ради благой цели — чтоб в вашем сыре аппе было меньше дырок
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9👍32
📕 Новый этап для библиотек — Android SDK Runtime (Privacy Sandbox)

Google предлагает:
🔵публиковать SDK отдельно от приложения
🔵запускать SDK в отдельном от приложения процессе

Если этот проект не забросят в долгий ящик, то в ближайшие годы правила игры заметно поменяются



Как сейчас:
🔵все библиотеки, подключенные к приложению, кладутся в apk и являются частью приложения

Как станет:
🔵приложение знает только API библиотеки, а реализация SDK загружается отдельно от apk и работает в изолированном процессе


Почему эта идея имеет смысл:

SDK смогут обновляться отдельно от приложений (в рамках мажорной версии)

у разработчиков SDK не будет полного доступа к данным приложения

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

соответсвенно, библиотеки могут сливать данные пользователя без вашего ведома

размер apk уменьшится (если это еще кого-то волнует)


Есть и обратная сторона:

если SDK обновляется в рандомный момент, то и приложение ломается в рандомный момент

усложняется схема жизненных циклов, ведь у SDK будет отдельный от приложения ЖЦ

не ясно, как это будет работать на устройствах без Play Market, откуда будут дозагружаться отсутствующие SDK


В первую очередь гугл раскатывает SDK Runtime с Android 14 для рекламных библиотек, а будущее зависит от фидбэка разработчиков

@dolgo_polo_dev
Please open Telegram to view this post
VIEW IN TELEGRAM
🤯20🔥8👍4🤔31