Лучший подход для запуска Activity из ViewModel в архитектуре MVVM

Я слежу за архитектурой MMVM в приложении. Все работало нормально, пока я не получил сбой, используя следующий код для запуска активности из ViewModel. Метод вызывается из XML с использованием привязок данных и передачей view в качестве параметра, а getApplication() - это метод из класса AndroidViewModel.

getApplication().startActivity(new Intent(view.getContext(), MyActivity.class));

Я считаю, что это произошло из-за того, что я не использую флаг NEW_TASK, так как начинаю деятельность вне класса Activity.

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

1. ViewModel с методом, который принимает Activity в качестве параметра и вызывает этот метод из фрагмента.

public startMyActivity(Activity activity){
   activity.startActivity(new Intent(activity, MyActivity.class));
}

Теперь добавьте листнер примерно так во фрагменте

mBinding.myButton.setOnClickListener(){
    viewModel.startMyActivity(getActivity());  
}

2. Добавление флага «Новая задача» в намерение и сохранение его в самой ViewModel.

Intent myIntent = new Intent(view.getContext(), MyActivity.class);
myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
getApplication().startActivity(myIntent);

3. Запустите Activity из самого фрагмента.

mBinding.myButton.setOnClickListener(){
   activity.startActivity(new Intent(activity, MyActivity.class));
}

Я считаю, что все эти подходы работают нормально, но есть вопрос

Можно ли иметь слушателей отдельно во фрагменте с использованием привязанных ViewModels для вызова метода из представления xml?

Я не уверен насчет второго подхода, если это все равно приведет к сбою приложения в какой-либо ОС.

Какой из них является лучшим с точки зрения архитектуры и перспективы модульного тестирования?

Следует избегать использования любых представлений Android в ViewModel или AndroidViewModel.

Chintan Soni 15.03.2018 06:38

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

pyus13 15.03.2018 06:41

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

pyus13 15.03.2018 06:45

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

Muhammad Babar 15.03.2018 06:49
7
4
5 160
1

Ответы 1

Я бы пошел для навигации внутри действий / фрагментов, но, конечно, в большинстве случаев вы хотите запускать навигацию из модели представления. Таким образом, вам нужно использовать команду из вашей модели просмотра, чтобы уведомить ваше представление (активность / фрагмент) для навигации в другом месте. Вы можете выполнить такую ​​«команду», используя LiveData, а точнее SingleLiveEvent.

SingleLiveEvent похож на любые LiveData, но запускает событие только тогда, когда вы явно устанавливаете для него значение, например, вы не получите его значение, когда начнете наблюдать за ним из вашего представления (активность / фрагмент)

Спасибо, я попробую и посмотрю, сработает ли это для меня.

pyus13 15.03.2018 20:58

Если у меня есть много возможных пунктов назначения с текущего экрана. Должен ли я иметь 1 SingleLiveEvent для каждого возможного пункта назначения? Что для этого лучше всего?

Archie G. Quiñones 21.02.2019 06:58

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

Samuel Eminet 21.02.2019 14:52

Другие вопросы по теме