Как стать автором
Обновить
6
0

Разработчик мобильных приложений

Спасибо большое. Думаю многим эти замеры пригодятся.
По поводу мини на m1 — при том же энергопотреблении и тепловыделении на x86, наверно, ничего собрать не получится. Однако, если не учитывать этот параметр, правильно подобранная машина на NVME будет быстрее за те же деньги.
Мини хорош для небольших и средних проектов. Единственный минус, который вижу — максимальный объем RAM в 16GB. Для крупных долгостроев этого уже будет мало.
Предпочитаю логику отделять от Android.
В данном конкретном случае адаптер, скорее, часть механики View. А вот дочерние фрагменты уже подключены к логике. В этом кейсе как раз и выгодно использовать Shared ViewModel — родительский фрагмент ее порождает, дочерние (из ViewPager) подключаются. При этом ничто Вам не мешает в дочерних порождать собственные ViewModel для, например, поставки данных.
Так или иначе, всю логику за пределы Android Вы не сможете вынести, как бы Вам не хотелось.
Такие же проблемы могут быть и у Safty args
Не могу представить себе такого кейса. Safe Args — просто обертка над аргументами. А один инстанс аргументов приходится на один инстанс фрагмента.
то эту breadcrumb логику я бы тоже перенес в сервис
Как говорится, «у любой задачи есть минимум 3 решения». Можно и по-Вашему, а можно взять готовое решение — Navigation Component + Safe Args, что обойдется дешевле во всех смыслах.
что я пытаюсь максимально абстрагироваться от Android, делая акцент на логике. Это помогает в тестировании и переходу к новым инструментам.
Ну вот для этого пакеты AndroidX поставляются с зависимостями для тестирования. Navigation Component не исключение.
Согласен с тем, что Shared ViewModel — не идеальное решение. Всё взаимодействие на нем завязывать не стоит. Но оно вполне применимо, например, в каких-нибудь пошаговых визардах. Это скорее полезный инструмент для определенного круга ситуаций.

Но и предложенный Вами сервис Shared ViewModel полностью не заменяет. Это уже отдаленно напоминает redux или mvi.
Остальное тоже не идеально. Опишу подробнее:

Мы строим ViewModel для конкретной View.
Не обязательно. В идеале ViewModel не должна знать о View, которая ее использует. Так мы разделяем логику (ViewModel) и механику (View) работы презентационного слоя. Таким образом, можно переиспользовать ViewModel на нескольких экранах схожего назначения. Например, можно использовать один и тот же тип ViewModel как в мобильной версии, так и в версии для Android TV.

Мы не можем просто взять такой фрагмент и добавить в ViewPager, например
И не нужно. Этим и распределением параметров должен заниматься наследник FragmentStateAdapter (или FragmentStatePagerAdapter). В идеале, по мере пролистывания, фрагменты должны создаваться и уничтожаться чтобы не мусорить в памяти. Решение этого вопроса сложнее, чем «просто добавить», и аргументы вполне подходят как часть решения.

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

ViewModel запрашивает параметры у сервиса по типу класса параметров.
И это порождает проблемы с уникальностью. Если у Вас в стэке несколько экземпляров одного и того-же фрагмента или фрагментов, которые используют один и тот-же тип параметров — после восстановления стейта Вы можете получить стопку одинаковых экранов.
Пример — экран профиля пользователя с параметром userId. Вы смотрите на профиль 3, в который попали из друзей профиля 2, в который попали так же из профиля 1. И в любой момент хотите вернуться к предыдущему. Да, в случае сервиса это решаемо, но в аргументах это всё уже решено.

Если объем передаваемых данных свыше 500 кб., то приложение может аварийно завершиться
Потому не стоит хранить в аргументах и saved state контент. Здесь надо хранить только параметры, и, в этом случае, лимит исчерпать довольно сложно.

Простите за большое количество текста. В паре строк эти вещи не опишешь.
Простите. Не уточнил. Имелось ввиду, что если с помощью FlowBindings реализовать подход пассивных view и им подобные. То есть сделать то же самое, что в примерах.
С одной стороны удобно, view можно переиспользовать. С другой — презентер жестко связан с тем набором методов и контролов, которые декларирует view и к другой view с другой механикой его уже не подключишь.
Как примеры жестких ситуаций — смена конфигурации или версия для AndroidTV. В обоих случаях может кардинально меняться не только интерфейс, но и механика работы. В идеале, об этих нюансах презентеру лучше не знать.
Есть вот такая реализация, но сырая.
Но многим (включая меня) подобные подходы не нравятся по причине того, что частично или полностью переносят механику view на presenter\view model.
Кажется, что они решают больше локальные чёткие задачи
Не совсем. По факту та же реактивщина, просто из коробки меньше конструктов и операторов. Как заявлено на странице Flow, главные цели — проще дизайн, дружественность к прерываниям и структурному параллелизму.
Да, есть конвертация в RxJava и обратно. Однако, на IO19 было объявлено, что для Jetpack первоочередной будет всё-таки поддержка корутин, а RxJava будет поддерживаться на уровне документации. Там же назвали корутины рекомендованным решением.
То есть те расширения RxJava, которые из коробки есть для Room и других компонентов — не понятно, насколько долго они будут существовать.
Имею много позитивного опыта по прикручиванию нового функционала на корутинах, архитектурных компонентах и так далее к легаси различной древности и размерности. Но да, это не всегда целесообразно.
Но речь шла именно о новых проектах. Тут, скорее, либо инерция, либо попытка доказывать профессионализм на волне чьего-то успеха.
Rx я думаю, тоже скоро начнут забывать…
Если Вы о RxJava от ReactiveX, то не скоро. Я хоть и сам широко использую Flow и корутины, но вакансий, где требуют RxJava и ее сторонников на руководящих должностях еще много. Людям не просто отпускать привычное.
Зачем этот промежуточный слой хранения?
Потому, что нужно разделять бизнес-логику и презентационную логику. Состояние далеко не всегда хорошо хранить в репозитории из-за того, что большинство операций повторяемые. Иначе это мало будет отличаться от поделок на EventBus 5 летней давности.
на мой взгляд не совсем верная формулировка
Тут согласен. LiveData, скорее, работает с ЖЦ Observer. Обычно это View, однако та же Navigation Library предлагает интересные приемы с LiveData.
Оценивайте тенденции)
Да, есть такая тенденция. Но до ее реализации еще далеко. А до тех пор стабильнее LiveData для выше обозначенных задач нет ничего, и с ней в прод еще ходить как минимум год.
Не в любой, но есть. Однако, все эти реализации интегрируются с жизненным циклом гораздо хуже LiveData. По своему опыту могу сказать, что со сторонними реактивными реализациями пока слишком много проблем.
Плюс ко всему, LiveData используется не только как прокладка между Rx и Flow.
Например, как управляющая компонента. Или в составе той же paging library.
ConflatedBroadcastChannel и скорый StateFlow
В них еще не скоро будет интеграция с LifeCycleOwner и прочими вещами. Всё-таки Flow — часть Kotlin Coroutines, а не Android. А даже если появится, то будем использовать прокладку в виде еще одного Flow вместо LiveData так как хранить состояние в UseCase не всегда нужно и редко полезно.
К тому же есть ViewModel
Вы опять смешиваете инструменты)
ViewModel сама по себе не решает задачу управления View в рамках жизненного цикла. Этим и занимается LiveData. На ViewModel же ложится задача переносить эти LiveData и содержать логику, которая управляет данными в LiveData.
Он не решает задачи смены конфигурации и хранения состояния. В ветке выше описал подробнее.
Потому, что Вы забываете про смену конфигурации. Она произойдет, хотите Вы этого или нет. В этом случае активити или фрагмент (View) будут пересозданы. Задача ViewModel в этом случае — перенести данные и отдать последние известные состояния View.
Здесь и видна разница между Flow и LiveData. Это разного порядка инструменты.
Flow — просто реактивный поток, способ организации следующих друг за другом событий. Он ничего в себе не хранит и при следующей подписке, в общем случае, запустит заложенный в него код заново.
LiveData — это mutable storage (цитата с IO19). Его задача — отдать последнее известное ему значение. В случае конвертации toLiveData() — последний отданный flow результат.
Итого, предположим, у Вас сетевой запрос завернут в flow{}. Без конвертации в LiveData внутри ViewModel, этот запрос будет выполняться при каждом, например, повороте экрана. LiveData решает в том числе и эту проблему.
а LiveData они задиприкейтят через какое-то время..
Нет. На IO уже не один раз говорили, что это разного рода инструменты с разным назначением. Потому деприкейт если и будет, то очень не скоро.
По поводу RN полностью согласен. Потому и написал про технически несложную идею. Но, в случае DePro, всё так же может упереться в наличие подходящего компонента. В обоих случаях его разработать относительно не сложно, но проблема одного порядка — нехватка гибкости и вариативности. При том, что RN работает на 2х платформах.
Вот как раз у бизнеса подобные решения не востребованы. Это не кардинально новая идея и ей не один год. Более того, существуют e-commerce платформы, которые нативные, гибкие и код практически писать не надо. Очередей за ними не видно.
Одно дело упрощать разработку, другое- уменьшать гибкость, вариативность и ухудшать UX.
Решение, конечно, само по себе интересное. Оно пойдет для того, чтобы пощупать рынок с технически несложной идеей. Только зачем, когда для этого есть Flutter и Reасt Native?
Сколько этих приложений? Просто, чтобы работать с таким, заказчик либо должен быть совсем нетребовательным, либо Вам придется подгонять компоненты или саму DePro под него. С этой стороны 85-90% уже крайне преувеличенная цифра. Вы просто судите только по той массе проектов, что прошли через Вас.
Если Ваш компонент покрывает группу View, то, если его механика хоть немного не совпадает с ТЗ — придется писать кастом. Примеров масса — списки с несколькими типами ячеек, пагинация через paging library, интерактивные списки (не только кнопочки), биллинг с библиотеками провайдеров. Список может быть большим, я только привел самое часто востребованное.
Если предлагаете покрывать каждую View компонентом — то это ничем не лучше слегка продвинутой вариации Data Binding, а современная MVVM на AAC будет гораздо компактнее и гибче (если знать как писать).
Решение безусловно интересное, но, увы, 85-90%, о которых Вы говорите, очень призрачны. Как и утверждение про «в 40-50 раз меньше кода». Это больше похоже на ошибку выжившего.
Всё дело в мелочах — для разных сервисов и приложений нужен разный UX, который тоже надо построить и прорабатывать. Это относится как к бизнес-логике, так и к механике интерфейса даже на типовых решениях.
Сведя всё к наборам поставляемых компонент теряется гибкость и вариативность. Для одних и тех же компонент механика может быть очень разной. Да, можно написать кастомные компоненты. А сколько их в итоге понадобится? Гибкости при этом не прибавится.
Так же есть вопросы к качеству выходного приложения. Например, как здесь работать с сменой конфигурации и восстановлением состояния?
Вы не первый, кто предлагает подобное и не только на Android. Такие решения так и не стали массово востребованными как раз по подобным причинам.
«А что мы, программисты, будем делать?». Он увидел минус в том, что при переходе на работу с библиотекой его могут сократить.
Если и сократят — значит он и раньше не был нужен. По-настоящему же стоит вопрос о востребованности DePro.
Спасибо! На самом деле примерно из-за подобных проблем с Moxy давно перешел на MVVM на компонентах. Но, конечно, о kmultiplatform тут говорить не приходится. И решений по выносу презентера на кроссплатформенную часть до этого момента не видел.
Но сразу напрашиваются два вопроса:
1. Как быть с сохранением состояния. Ну то есть, для примера, в компонентах для тяжелых случаев есть SavedStateHandle.
2. Если презентер на стороне kmultiplatform, выходит нельзя воспользоваться, например, paging library и придется городить велосипеды для пагинации?

P.S.
Было время, когда я пробовал Google MVVM, но как-то слишком много кода получается для решения, казалось бы, простых задач
На самом деле объемы кода те же, просто не все смотрят на практики.
Совет: вот отличная серия для того, чтобы узнать основы разработки RxJava для Android.
Довольно странный совет с учетом того, что официально рекомендованным решением для построения асинхронности являются kotlin coroutines. А для поточной реактивщины там есть kotlin flow.

В остальном согласен.
Skype и VSCode — это веб-приложения
Я бы не назвал их эталонами качества, хоть и пользуюсь последним довольно часто.

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

А вот всякие кордовы, электроны и прочие фреймворки, у которых вшитый браузер весит больше, чем само приложение — это уже веб-фреймворки. И они в мобильной среде сейчас совсем не популярны. Интересно почему?..

Такая большая и богатая компания, а пишет своё мобильное приложение на веб-технологиях. Почему?
Об истинных мотивах мы можем только гадать. Но многие богатые компании RN в итоге выкинули, что тоже показатель.

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

Вот веб и есть самый привычный и распространённый интерфейс
Почему же тогда у инстаграма основной интерфейс именно нативный, а веб сильно обрезан? Вы рассуждаете о теплом и мягком. Вэб у натива тоже много перетянул. В частности и Material Design, и hot reload (он появился на андроиде (и не только) в разных реализациях далеко до RN).

веб всё равно развивается быстрее всех этих платформ, это он задаёт им тренды
Очень спорно. Те же Google Pay и Apple Pay на вэбе стали доступны не сразу. Как и мультитач, работа с гео и прочее.
Даже десктопные и мобильные приложения легче и эффективнее писать на всяких Иониках и Электронах, а не на WinAPI
Не проще, а дешевле. При том скупой платит дважды так как выходное качество часто оставляет желать лучшего. Начиная от расхода памяти, заканчивая проблемами рендера.
миллионы сайтов с навороченным дизайном, адаптивностью, реактивностью, анимациями и прочими ништяками, о которых другие платформы могут только мечтать
Поверьте, популярные платформы в нативе позволяют гораздо больше если у Вас достаточно опыта. Только никому не нужны навороченные интерфейсы. Есть такие штуки, как гайдлайны и пользовательский опыт. И они говорят о том, что людям проще и эффективнее использовать уже привычные интерфейсы.
благодаря этому он превратился в Самую Главную платформу
Если бы это было возможно — это бы уже произошло. Самое близкое к тому, о чем Вы говорите — ChromeOS, популярность которой далека от высокой. А, по факту, бОльшая часть пользовательского трафика сейчас идет с мобильных устройств, где доминируют приложения а не сайты из браузера.

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

А она заключается в том, что Binder и IBinder — части одного и того же RPC-механизма. А значит порождают строгую ссылочную зависимость.

Не надо путать RPC с remote storage.

Информация

В рейтинге
Не участвует
Откуда
Россия
Зарегистрирован
Активность