Должны ли мы использовать ViewModels для связи между 2 различными фрагментами или пакетами в одной архитектуре приложения деятельности?
Сценарий 1. Если мы используем ViewModels
для связи между фрагментами, то ViewModel
должен быть создан по ссылке на действие и, следовательно, будет оставаться в памяти до тех пор, пока действие не будет уничтожено.
Сценарий 2. В потоке мастер-детализация ViewModel
облегчает нашу жизнь, но опять же возникает проблема с использованием памяти.
Сценарий 3. У нас есть viewModelScope
в новой версии архивной библиотеки для отмены заданий с жизненными циклами Fragment/Activity, но если ViewModel
создается со ссылкой на действие, он будет оставаться там до тех пор, пока действие не будет уничтожено. Следовательно, задание все еще может выполняться, а фрагмент уже пропал.
Ответы
Ответ 1
Вы можете использовать ViewModels для связи между двумя разными фрагментами (иначе говоря, SharedViewmodels), потому что это просто, но не идеально.
Как вы знаете, SharedViewModels должны быть живы до тех пор, пока не будет жив первый родительский элемент (действие или фрагмент).
но подождите...
Какова цель ViewModels?
Мы создаем ViewModels только для связи между фрагментами? Абсолютно нет.
Является ли использование ViewModels против цели ViewModels? нет, я говорю, что не идеально использовать их для связи между фрагментами, но если у вас небольшой проект, вы можете использовать их, потому что это просто.
Так что я могу сделать вместо использования ViewModels для связи между фрагментами? Вы можете создавать независимые компоненты пользовательского интерфейса и использовать их для связи между фрагментами.
В чем преимущество создания этих странных независимых компонентов пользовательского интерфейса? Таким образом, каждый компонент имеет свой собственный ViewModel (или Presenter), и они не имеют никаких родительских/дочерних отношений; Вместо этого они обновили ту же бизнес-логику или в реактивном программировании, они просто наблюдают ту же модель.
Что означает создание независимых компонентов пользовательского интерфейса и как их создавать? если вы уже знакомы с реактивным программированием, я рекомендую прочитать этот потрясающий пост в блоге Ханнеса Дорфмана; Если вы этого не сделаете, я просто предлагаю использовать библиотеку EventBus для связи между фрагментами, но вы скоро поймете, что чрезмерное использование этой библиотеки приводит к спагетти-коду.
Ответ 2
Сценарии
Если фрагменты не являются частью потока/группы, то не делитесь ViewModel, просто передайте некоторый идентификатор/данные новому фрагменту, создайте его собственную модель представления и запросите данные для фрагмента из его собственной модели представления.
Если фрагменты являются частью какого-либо потока/группы (корзина/оформление заказа/процесс бронирования, многоэкранный процесс регистрации, фрагменты окна просмотра и т.д.) И логика является достаточно общей, то делите модели представления между фрагментами. В архитектуре с одним действием я помещаю эти поток/процесс в его собственный корневой родительский фрагмент, который действует как хост и используется для создания области видимости модели. Например:
MainActivity ->
-> RootAuthFragment
-> SplashFragment (replace with below)
-> LoginFragment (add to backstack with below or onsuccess login go to MainFragment)
-> SignupFragment (onsuccess go to Main)
-> MainFragment (replace with RootAuthFragment)
В приведенном выше сценарии вы можете поделиться моделью представления между экранами входа и регистрации с областью RootAuthFragment. Если у вас есть многоэкранный процесс регистрации, вы можете переместить его в отдельный корневой фрагмент и создать отдельную модель представления для потока регистрации.
Пакет vs ViewModels:
Связки используются для передачи некоторых значений. Так что, используйте это только для этого. Я использую связки, чтобы обычно передавать примитивные типы данных или перечисления, и на основе этого я запрашиваю фактические данные из модели представления (через комнату Android или модернизацию) или, если объекты данных достаточно малы, я делаю их пригодными для передачи и просто пропускаю.
Если у вас есть общая ViewModel, и она становится классом бога и делает много разных вещей, то это означает, что эти фрагменты нуждаются в отдельных ViewModel. Не делитесь ViewModel только для данных. Поделитесь ViewModel для общего/общего поведения/данных/логики (что имеет смысл для ваших конкретных случаев использования)
Ответ 3
Я предпочитаю, чтобы вы использовали подход View Models, если вы используете единую архитектуру действий. Чтобы оправдать мой ответ, я проясню ваши сценарии здесь.
Сценарий 1. Если мы используем ViewModel для связи между фрагментами, то ViewModel должен быть создан по ссылке на действие и, следовательно, будет оставаться в памяти до тех пор, пока действие не будет уничтожено.
Сценарий 2. В потоке основных деталей ViewModel делает нашу жизнь проще, но опять же проблема с использованием памяти есть.
Что касается памяти, то вы уже храните информацию в памяти, из которой вы не сможете убежать. Если вам не нужны данные для того, чтобы оставаться там, вы можете очистить данные и от моделей, но опять же это убьет цель хранения данных в первую очередь.
Если вы передаете данные с помощью связки, они также будут занимать память там.
- Сценарий 3. У нас есть viewModelScope в новой версии архивной библиотеки для отмены заданий с жизненными циклами Fragment/Activity, но если ViewModel создается со ссылкой на действие, он будет оставаться там до тех пор, пока действие не будет уничтожено. Следовательно, задание все еще может выполняться, а фрагмент уже пропал.
Именно основная цель использования представлений моделей заключается в сохранении последнего состояния для пользователя, с которого он ушел.
Ответ 4
Да, вы должны использовать модели просмотра для связи между двумя фрагментами одного действия.
Ответ 5
Согласно https://developer.android.com/topic/libraries/architecture/viewmodel состояниям
Этот подход предлагает следующие преимущества:
The activity does not need to do anything, or know anything about this communication.
Fragments don't need to know about each other besides the SharedViewModel contract. If one of the fragments disappears, the other one keeps working as usual.
Each fragment has its own lifecycle, and is not affected by the lifecycle of the other one. If one fragment replaces the other one, the UI continues to work without any problems.