Старый Мобильщик
74 subscribers
34 photos
1 video
1 file
118 links
Разработка мобильных приложений, дедлайны и все, что вы любите в IT.

Будни. Сниппеты. Заметки.

Когда-то были AsyncTasks ... Android 2.3.3 и ни одной вакансии в городе-миллионнике

Обсудить что-либо: @activitynotfound
Download Telegram
Старый Мобильщик
Как вам впечатления от новой студии? Уже привыкли, что Emulator стал частью окна студии? 🙂 p.s. Странные баги на Mac OS тоже присутствуют (как обычно), но в целом жить можно. А вот Preview нормальный для Compose так и не завезли. Все равно build - refresh…
Хм, а кстати завезли некий "Hot Reload" для Compose без повторных билдов. Меняешь размер шрифта и сразу изменение на экране эмуляторе. Хмм. Надо бы изучить, что еще может эта фича.
Другое дело!
👍1
Первое впечатление от Flutter

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

Кстати, для этого поста я поговорил с коллегой, который разработал еще год-два назад на аутсорс для британского заказчика приложение на Flutter. Скачал, поигрался с этим приложением - работает в целом шустро и каких-либо косяков особо не заметил. И, кстати, у него уже 1 млн установок и рейтинг 4.4, что довольно неплохо.

Что понравилось во Flutter:
1. Интуитивная простота. Для быстрого старта дока хороша и все нужное легко найти. Да и сам Flutter довольно дружелюбен для новичка, а всю доку можно просмотреть за полдня.
2. Куча готовых пакетов на pub.dev. Все еще есть, казалось бы простые, задачи для которых пакетов или их функциональности не хватает, но их количество явно растет с каждым годом.
3. Все - виджет. Даже разделитель во Flutter - это виджет.
4. Hot Reload - прекрасен. Меняете код и у вас обновляется приложение в эмуляторе. Это прям веб-приложение в мобильном мире!
5. Куча готовых виджетов на все случаи жизни: https://docs.flutter.dev/development/ui/widgets/layout
В данном случае, куча - в хорошем смысле!
6. Один UI на все платформы. И на Android, и на iOS, и на Web, и на Desktop.
7. Тут могу ошибаться, но во Flutter нельзя использовать рефлексию (скорее всего для производительности UI?) и именно поэтому парсить JSON-чик приходится несколько сложнее, чем вы привыкли. Нужно установить либу, настроить генератор кода для вашей модельки (благо не сложно), запустить и вуаля. Тут, конечно, все сложнее. Можно, обойтись и стандартными средствами, но будет больше кода и менее привычно после всяких GSON.
8. Плюшки языка. В Dart есть async / await, поддержка nullable-типов из коробки. Мелочь, а приятно.
9. Compose явно пилили с похожими мотивами и идеями Flutter. Ну или скорее Flutter пилили похожим на React / Redux. Изучая Flutter или Compose, становится проще в смежной теме.
10. Встроенный роутинг и механизм состояний, хотя есть множество сторонних либ. Одновременно и плюс и минус.

Что не очень понравилось:
1. В тоже время Dart - довольно странный язык, к которому нужно привыкнуть. Вроде бы не самый старый язык, но, например, везде в конце выражения требуется ; Не то, чтобы Dart вызывает какой-то особый негатив, если вы хорошо знакомы с Java, но забавные (странные) вещи встречаются. Плюс нужно закладывать время на его изучение.
2. Некоторые вещи делаются сложнее (тот же парсинг JSON), но некоторые и проще.
3. Отладка - отдельная песня к которой нужно привыкать. То ли еще не разобрался, но логов как-то не хватает. Для отладки, кстати, поднимается локальный сервер и там можно смотреть память и прочие вещи. Хорошо, что есть, но непривычно, что не в IDE.
4. Некоторые вещи не реализованы и нужно допиливать либо существующие плагины, либо писать самому. Для простых приложений, наверное, не очень критично.
5. Множество подходов по созданию архитектуры. Не то чтобы прям сильный минус, потому что тоже самое есть на любой платформе, но есть популярный BLoc-s, а можно обмазаться и стандартными классами State, а еще есть два-три популярных подхода. Тут нужно изучать детальнее каждый, но для начала воспользуемся стандартным и чуть позже уже BLoc.
6. Вложенность и вертикальный код. Виджет в виджет, в другой виджет и т.д. Во-первых, сильной вложенности нужно избегать в принципе, так как теряется производительность. Во-вторых, читать такой код сложнее, когда множество атрибутов и вертикальный код (как-нибудь покажу пример).
7. Популярность в Китае и Индии. Тут двоякая история. С одной стороны это не дает Гуглу закрыть проект (хотелось бы верить), с другой - сами понимаете. Качество проектов, которые придут к вам на поддержку, кода не всегда будет хорошим, как и качество сторонних плагинов (либ).

Вроде бы все.
Код и примерчики будут позже, как поправлю парсинг и доделаю главный экран.
👍2
Еще немного о виджете поиска на Compose

Посидев с дизайнером, посмотрев виджет поиска, я решил переделать основу для компонента. В текущем решении на базе OutlinedTextField не хватало гибкости. Например, нельзя задать отступы от текста до иконки.
Самое быстрое и правильное решение - использовать для основы BasicTextField.

У BasicTextField есть composable decorationBox который позволяет сделать любой сложности вьюшку вместе с полем ввода. Например, в нашем случае мы вложили поле ввода в Row и поместили по краям от текста иконки на нужном расстоянии (для читабельности код немного сократил):

decorationBox = { innerTextField ->
Row(
...
) {
Icon(
...
)
Spacer(modifier = Modifier.padding(start = 4.dp))
Box(contentAlignment = Alignment.CenterStart) {
if (showHint.value) {
Text(
text = hintText,
...
)
}
innerTextField() // наше поле ввода
}
if (text.value.text.isNotEmpty()) {
Icon(
...
)
}
}
}

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

Row(
modifier = Modifier.border(
if (isFocused) 2.dp else 1.dp,
animatedBorderColor,
shape = RoundedCornerShape(cornerRadius)
)
.defaultMinSize(minHeight = 40.dp)
.clipToBounds()
)

Полную версию закинул на GitHub: https://github.com/Djangist/ComposeSearchView/blob/main/SearchView.kt
Пользуйтесь.
👍1
Как-то рассказывал вам про Charles Proxy и тогда были восторженные отзывы об этом инструменте!
Но... однажды услышав про ProxyMan от коллеги, решил попробовать его в деле. Уже месяца 3 или 4 сижу на этом прекрасном проксике. И скажу вам: если у вас Mac - лучшего тулза для отладки приложения я еще не видел.

Почему вообще перешел на ProxyMan?
В основном, из-за не самого удобного интерфейса настройки локальных моков API в Charles (плюс там нужно постоянно с файлами возиться), а у нас в банке это довольно нужная и востребованная фича на которую не хочется тратить кучу времени. В ProxyMan поменять какой-то ответ можно буквально за пару кликов через контекстное меню мышкой и это круто! Экономит кучу времени.

Во-вторых, более интуитивный интерфейс и больше возможностей.
Например, буквально вчера решил посмотреть есть ли эмуляция медленной сети и потери пакетов.
И как вы думаете?
Да, есть. Опять же, экономия времени. Легко и просто проверил shimmer-анимацию или какие-то состояния ошибок.
И вы же понимаете главный прикол, да? Не нужно перезапускать приложение в эмуляторе или на девайсе! Меняешь ответы, состояния и тестируешь приложеньку.

И наверное, не самый последний аргумент - у ProxyMan есть бесплатная версия. У нее, естественно, есть ограничения, но пока каких-то проблем с ними для мобильщика не встретил. Да, ограничение в 4 домена, но этого хватает.

Отдельно хочу отметить удобный форматтер для Json и подсветка. Читать длинные ответы API оч удобно.

И конечно, прекрасная документация, которая не ради галочки.

Вообщем, маковадам рекомендую 👉 https://proxyman.io
Жаль, что не реклама 🙂
👍2
Что новенького в рассылках #7

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

Хороший пост про Preferences Data Store
и там же про Proto Data Store - Data Store, который использует Protocol Buffers

Анимация в Compose. 4 примера с кодом.
Compose постоянно дорабатывается, поэтому важно следить за обновлением API. В том числе и по Animations API, часть которого недавно была все еще в статусе Experimental.

Пост о том, как начать создавать дизайн-систему на базе Compose. Стоит ли рассказать, что такое дизайн-система?

Действительно интересный пост про оптимизацию запуска и работы приложения с помощью Baseline Profiles

Наглядный пример в стиле Rx про методы merge, zip, combine для Flow

Пост про автоматизацию создания скриншотов UI на базе Compose. Как вариант использования: написать UI-тесты и делать скриншоты разных состояний экрана. Потом отдать этот набор скринов QA Team или самостоятельно просматривать и искать косячки.

Вводная по KMM на наглядном примере с советами как шарить код между платформами

Пример связки Compose и библиотеки Molecule от CashApp в которую контрибьютит Jake Wharton

Подборка ссылок для изучения KMM

Советы по оптимизации производительности кода


Библиотеки
О-как! Официальная либа с поддержкой Maps SDK для Compose

Codegen-plugin для GraphQL

Либа для загрузки изображений. Поддерживает Glide, Coil и Fresco. Мы себе уже подтянули.

По-моему, и раньше была в нашей подборке, но мало ли. Либа-сахарок для ViewModels Lifecycle-properties

Мультиплатформенный 2d-движок для создания игр. Поддержка Android в работе, iOS - позже.

Библиотека для создания adaptive and responsive UI на базе Jetpack WindowManager
👍2🔥1
В последнее время все чаще приходят вакансии из банков. Уже ровно год, как я работаю в частном банке (не Тинькофф) и если хочется почитать об этом опыте и как тут все устроено - знаете что делать.
Интересно?
(голосование продлится до завтрашнего вечера)
Final Results
100%
Да
0%
Нет
Начал набрасывать текст про работу в банке. Пока сумбурно, водянисто - выходит дольше, чем думал. В итоге поделю-ка весь опыт на 4 поста с разными темами: общее впечатление, процессы, люди и код.

А пока для затравки оставлю здесь ответ на самый интересующий многих вопрос: норм ли платят?
Да, норм. Я уже несколько лет работаю как ИП на патенте и даже в таком случае ЗП выходит достойная. Выше чем на начальных порах в том же Яндексе, но в стартапе до этого выходило побольше за счет ЗП в USD. И даже учитывая огромную инфляцию на продуктовую корзину (в том числе и в нашем Мухосранске) - грех жаловаться.

Всем продуктивной недели!
👍3
Общее впечатление от работы в банке

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

Запасайтесь кофейком, чаем или чем-то покрепче.
Первый пост из серии готов.
👍7
Уже несколько дней сложно себя заставить ни то что работать, вообще что-либо делать.
Сегодня буду пытаться все же что-то полезное сделать по работе, а фоном вместо новостей и прочего шлака поставил 37 часовой курс по Flutter для начинающих
Надеюсь, у вас все хорошо.
Берегите себя!
👍3
Любопытный факт, о котором, я, например, не знал.

Во многих учебниках по программированию моего времени переменные в циклах обычно обозначаются как i. Знаете почему?
Дело в том, что более 60 лет назад в первоначальной версии языка Fortran (на синтаксис которого оказала большое влияние алгебра) переменные, имена которых начинались на буквы от I до N, были целочисленными.

В современных языках, понятное дело, лучше переменные циклов называть более осмысленно.
👍3
Интересно, а давно Яндекс начал нанимать Flutter-разрабов? Или это такая реакция на текущие события?
Заметили тренд на коррекцию рублевых зарплат?
Некоторые компании, конечно, и раньше могли себе позволить платить столько архитекторам, но и в Mobile на рядовые позиции коррекция намечается.

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

p.s. потихоньку приходим в себя. Начал набрасывать вторую часть статьи про работу в банке. Поговорим в этот раз о процессах.
👍1
Работа в банке. Часть 4. Код.

Ну что, соскучились?
Пока еще производительность хромает. Как в работе, так и вообще везде. Медленно, медленно приходим в себя, но все еще больше с акцентом на просмотр новостей 😞

Но я таки набросал последний пост про работу в банке.
Запасайтесь по классике любимым напитком, букв много.

Всем хороших выходных!
👍3
Попробовал удобный и быстрый способ протестировать диплинки в Android-приложении.
Просто запускаем команду:

adb shell am start -a android.intent.action.VIEW -d "deep_link_url" app_package_name

И приложение запускается с нужным диплинком.
Красота!
👍1🔥1
Любопытный баг нашелся в Compose:
https://issuetracker.google.com/issues/192433071

Суть: при нажатии на Back сперва сбрасывается фокус поля вместо перехода на предыдущий в стеке экран. Приходится дополнительно тапать на Back.
Статус у бага вроде бы уже fixed, но пока не ясно до конца в какой версии исправят. На текущей стабильной версии Compose 1.1.0 вроде бы еще проявляется.

Вариантов исправить несколько, но если не сильно заморачиваться, то просто к полю ввода добавляем такой вот костыль-модификатор:

modifier = Modifier
.onKeyEvent {
if (it.key == Key.Back) {
// presenter.onBackPressed() or something like
true
} else {
false
}
}

Ждем включения фикса в основную версию.

p.s. Давненько я что-то ничего не постил… в общем как вы там поживаете в ваших Грузиях / Армениях ? 🙂
👍4
Я снова с вами!

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

Кстати, теперь у постов будут теги для быстрого поиска.

Что новенького?
1️⃣ В банке сменилось руководство (теперь российское), но изменений в плане работы пока особых нет. Работаем как и раньше. Ограничений на работу из-за рубежа тоже нет, в отличии от Альфы, Сбера и еще парочки банков. Вот коллегам из Открытия (по слухам) тяжелее всего. Хотя, ВТБ многих заберет к себе, если покупка осуществится.
2️⃣ Потихоньку наша махина переходит на рельсы MVI + Compose. MVI пока самописный, благо не так чтобы сложно его реализовать в базовом виде. По Compose вроде дела идут неплохо: переносим свои компоненты на него, что-то выкидываем, ибо хватает стандартной поддержки, но все упирается как всегда во время.
3️⃣ Активнее начали заниматься написанием тестов и скоро их количество в конкретном функционале будет проверяться на CI. Сделаем минимально допустимое покрытие перед мержем ветки в dev.
4️⃣ В Сентябре переболел ковидом, но в легкой форме, поэтому полет нормальный.

А как у вас дела?
👍4
В xml-разметке когда привязываете элемент к top и bottom других элементов, используя ConstraintLayout, по-умолчанию нужный кусок макета займет не всю область между двумя другими и нужно проставить ему height = 0dp. Частый кейс!

В Compose если поставить у этого элемента в модификаторе height = 0.dp это не сработает.

Оказывается, подобная опция есть в методе constrainAs и нужно выбрав либо ширину, либо высоту указать опцию fillToConstraints:


Modifier
.constrainAs(content) {
bottom.linkTo(termsAndConditions.top)
top.linkTo(topBar.bottom, margin = 32.dp)
...
height = Dimension.fillToConstraints
}


Теперь элемент растянется по всей высоте.

#Compose #ConstraintLayout
👍1
Кто бы мог подумать, что в 2023 я буду прикручивать к Android-приложению снова веб-сокеты? Еще когда только технология появилась все в мобильном мире считали как должное, что нужно обязательно их попробовать затянуть в проект. Потом все как хапанули с ними, особенно, в кейсах, когда нужно работать с сокетом из нескольких мест в приложении и держать коннект в фоне, который так и хотел где-то закрыться или память покушать. Видимо mobile-мир, как и человечество развивается по кругу (ну или просто архитекторы у нас вызывают вопросы?). Теперь ждем снова, когда будем хапать кое-чего на лопате.

Благо, если не нужна очень гибкая его настройка, можно воспользоваться либой, которая подключена почти в любом проекте - OkHttp:

webSocket = builder.newWebSocket(
Request.Builder().url(url).build(),
webSocketListener
)

и дальше работать с объектом WebSocket.
Минус реализации в OkHttp в том, что вы не можете гибко контролировать коннект. Есть только открытие сокета, закрытие и отправка / получение сообщения. Хотя может и есть, я пока не встретил сходу, при том что в исходник тоже заглянул.

Как думаете зачем в банке могли потребоваться веб-сокеты в 2023?
Нет, не для чата 🙂

#WebSocket
👍4