MvxAsyncCommand handler and UI lifecycle #4171
Unanswered
NickPapatonis
asked this question in
Q&A
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
For starters, we're still using version 6.3.1, and upgrading is not going to be possible in the near future. I've looked around for guidance on this question, but haven't found anything that specifically answers our issue.
Background
We have numerous MvxAsyncCommand handlers responding to user button clicks/taps. These handlers range from simple to somewhat more involved in terms of what they need to do. They might simply save some data and then use the navigation service to close. Or, they might have to prompt the user (sometimes more than once) with a dialog in order to determine how the handling should be done. An example would be something like the user completes everything on a task list. The handler for the last one might ask if the user wants to close the task list on the server (i.e., set its state to closed) or keep it open since we allow adding new tasks on the fly. So, the handler has to do some checking, ask some questions and then complete the whole command based on this information.
Issue
While the handler is executing, the user might do something that puts the app into the background. Once there, certain UI or navigation related operations are no longer appropriate or safe since there is no current, top activity. For example, attempting to close a fragment with the MvxNavigationService.Close while in the background will generate an unhandled exception (this is easy to reproduce in version 6.3.1, or I can get a sample together if needed).
Note that our handlers are not running for very long. It's just that the user is often doing something (e.g., switching apps quickly or putting the device to sleep) with just the right timing such that our handler is in mid-flight when they do.
Our Solution (so far)
We've started implementing code in our view models (actually in a base class) that creates a "ViewAppeared" task which is completed whenever ViewAppeared is called and recreated if necessary whenever ViewDisappearing is called. The base class also makes a protected method available to await the ViewAppeared task. With all of this, our command handlers now await the ViewAppeared task before doing anything that might be unsafe if in the background. However, this seems like a lot of extra infrastructure for something that must have already been solved. Plus, we are finding some scenarios where onResume/ViewAppeared is invoked on fragments when you would not expect. For example, every tab fragment (not just the first or selected) in a view pager is resumed after creating and starting even when not truly visible. In this case, there is no convenient way in the view model to detect that the fragment is really not the currently visible tab fragment.
Question
It seems like this is a general enough issue that there should already be something to help with this, either something built into Android, Xamarin or MvvmCross, or some guidance/best practices to do this properly. Has anyone else dealt with this issue? Any advice or resources would be really appreciated.
Thanks
Beta Was this translation helpful? Give feedback.
All reactions