Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

popBackStack in onPostExecute causes IllegalStateException

Apologize this is a fairly long post, let me try to explain the background first:

I've read a lot of posts on this topic (and Alex's excellent blog post on this topic), and the general conclusion seems to be not perform fragment transactions in an async callback (see Dianne's post), like AsyncTask#onPostExecute().

However I have 2 cases where this is necessary:

  1. An Activity showing a login Fragment, when user press the login button, an AsyncTask starts to authenticate with server, then when login success is returned, the login Fragment is replaced with the main app Fragment.

  2. An Activity showing the main app fragment, when user triggers some action that requires logging in, a login fragment replaces the main fragment which is added to backstack. Again when the login button is pressed, AsyncTask authenticates with server, then when login succeeds, we want to pop backstack to reveal the main Fragment to the user and let them do the action they wanted to perform.

Case 1 can be solved by using commitAllowingStateLoss, but Case 2 is tricky as there is no such flavor of popBackStack in FragmentManager.

In any case, both of these cases require special handling of app going to background during AsyncTask#doInBackground(), causing onPostExecute() getting called when app is in background. One solution is to use Fragment.isResumed to guard replace fragment or pop backstack, and then handle process killed situation by logging in again or save some flag indicating a successful recent login and replace/pop the login fragment on app restore state (login Fragment is restored to top by FragmentManager). Or allow state loss, and handle process killed then restored situation, check recent login and remove the login fragment.

Is this how you would handle this? It feels like a lot of work just to handle a very common situation.

like image 305
dvd Avatar asked Mar 22 '23 10:03

dvd


1 Answers

A more recent workaround is to call FragmentActivity.onStateNotSaved() before popBackStack().

like image 170
TalkLittle Avatar answered Mar 25 '23 00:03

TalkLittle