I am following MMVM architecture in app, Everything was working fine untill I got a crash using following code to start an activity from ViewModel. Method is called from XML using databindings and passing view
as parameter and getApplication()
is the method from AndroidViewModel
class.
getApplication().startActivity(new Intent(view.getContext(), MyActivity.class));
I believe it was because I am not using NEW_TASK flag since I am starting activity outside an Activity class.
Now there are following solutions I could think of but not sure which one is best based on architectural point of view.
1. ViewModel with a method which takes Activity
as parameter and call that method from a fragment
public startMyActivity(Activity activity){
activity.startActivity(new Intent(activity, MyActivity.class));
}
Now add a listner something like this in fragment
mBinding.myButton.setOnClickListener(){
viewModel.startMyActivity(getActivity());
}
2. Adding a New Task flag to intent and keep it in ViewModel itself
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. Start the Activity from fragment itself
mBinding.myButton.setOnClickListener(){
activity.startActivity(new Intent(activity, MyActivity.class));
}
I believe all these approaches works fine but a question in mind
Is it ok to have listeners seprately in Fragment insted of using binded ViewModels to call method from view xml?
I am not sure about the second approach if that will still crash the app in some OS.
Which one is the best approach from architecture point of view and unit test prespective?
I would go for navigation inside activities/fragments but of course most case you wanna trigger your navigation from view model. So you need to use a command from you view model to notify your view (activity/fragment) to navigate elsewhere. You can do this kind of "command" using LiveData and more specificly SingleLiveEvent .
SingleLiveEvent is like any LiveData but trigger an event only when you explicity set a value to it, for example you won't receive its value when starting observing it from your view (activity/fragment)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.