Q:

Android MVP - Detaching view (onPause VS onDestroy) and state preservation

I'm trying to implement the MVP architecture in my app.
However, after reading some blogs and viewing some sample project samples, I'm not sure I completely understood where is the right place to detach the view, and what should be done once the view attached for the second time after an async operation.
Most of the examples I saw, just sum it all up with a view's null validation check after an async call.
I'll try to make my point clear with an example - Login/Registration by phone number (The main idea is the important thing, and not the example itself)
There is an activity which display a fragment - LoginFragment.
The user enters his phone number and tries to login.
If the user exits - he should get navigated to another activity (after entering the code received by sms..)
If the user doesn't exits, he should get navigated to registration process - RegistrationFragment.
If there was an error, a dialog with error message should appear, ErrorDialogFragment.
Now, in a happy flow where the user presses the login button and waits until the process complete, all good.
But, in a less happier flows (not so frequent ones, but definitely can't get ignored), the user presses the login button and after that presses the home button or alternatively gets a phone call.
In scenario 1, where we attach/detach the view in onCreate/onDestroy, once the async login operation finish and we should replace to RegistrationFragment or show ErrorDialogFragment, there is a chance we will meet the famous IllegalStateException:
getting exception "IllegalStateException: Can not perform this action after onSaveInstanceState"
In scenario 2, where we attach/detach the view in onResume/onPause, once the async login operation finish we won't be able to replace fragment or show a dialog because the view is already detached.
In this case, I'm not sure what is the right thing to do.
Should we go with scenario 1 and commit the transaction with commitallowingstateloss?
I'm afraid it is a bad idea.
Or Should we go with scenario 2. In this scenario, we should act accordingly when view attached again, which means saving states (RegistrationRequied, ErrorHasOccured, LoginProcessStillRunning, etc..) in the Presenter/Interactor.
Can someone can shed some light regarding this?
Thanks in advance!

A:

Oh the joys of the Android lifecycle. I feel your pain.
In my personal experience, resorting to commitAllowingStateLoss is usually a symptom of trying to update your Ui (View) while in the background (and as you note, the ui may be destroyed).
What I would suggest is that you don't try to update your ui without checking if the activity has been backgrounded (onStop or onPause depending on the situation). If your ui has been backgrounded, remember the changes you need to make and do them when your Ui is reconnected (onStart or onResume depending on the situation).
In essence I'm saying you should follow Scenario 2. And yes. You will have to save quite a bit of state somehow.
Unfortunately this isn't easy and there are many approaches to doing this ranging from using event buses, all the way through to using RxJava.
Every approach has it's advantages and flaws and they are all really too complex to discuss in detail in a single post.
However, I have a blog post I wrote some time ago on a way of doing this in a way that doesn't require additional libraries.
It's a little out of date now, but it may give you some ideas: A Simple MVP aproach for Android
All the best.
Kind regards,
Chris.

