Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

commitAllowingStateLoss() and commit() fragment

I want commit a fragment after network background operation. I was calling commit() after successful network operation but in case activity goes to pause or stop state it was crashing app saying IllegalState exception.

SO I tried using commitAllowingStateLoss() and its working fine now.

I gone through few blogs and articles it says commitAllowingStateLoss() is not good to use.

Whats the way to handle commit fragment after network operation handling activity pause and stop state?

like image 732
amodkanthe Avatar asked Mar 09 '17 06:03

amodkanthe


People also ask

What is difference between commit and commitAllowingStateLoss in Android?

There is only one difference between commit() and commitAllowingStateLoss() : the latter doesn't throw an exception if state loss occurs. Other than that, they have identical behavior.

What does commitAllowingStateLoss () method do?

commitAllowingStateLoss. Like commit() but allows the commit to be executed after an activity's state is saved.

What is Fragment transaction?

At runtime, a FragmentManager can add, remove, replace, and perform other actions with fragments in response to user interaction. Each set of fragment changes that you commit is called a transaction, and you can specify what to do inside the transaction using the APIs provided by the FragmentTransaction class.

What is the use of addToBackStack in Android?

Calling addToBackStack() commits the transaction to the back stack. The user can later reverse the transaction and bring back the previous fragment by pressing the Back button. If you added or removed multiple fragments within a single transaction, all of those operations are undone when the back stack is popped.


1 Answers

I'd like to add informations to Aritra Roy (so far i readed, it's a really good answer).

I encountered the problem before, and i found that the main problem is that you are trying to make some async operations (HTTP, computations, ...) in another thread, wich is a good pratice, but you must inform your user AFTER receiving answers.

The main problem is that as it is async operations, there is no guarantee that the user is still on your activity/app anymore. And if he went away, there is no need to do UI changes. Moreover, as android may kill your app/activity for memory issues, you have no guarantees to be able to get your answer, and save it to be restored. The problem is not only "the user can open another app" but "my activity can be recreated from configuration change" and you may be trying to do UI changes during activity recreation which would be really, really bad.

Using "commitAllowingStateLoss" is like saying "i don't care if the UI is not really in the good state". You can do it for little things (like activate a gif saying your download ended)... That's not a big issue, and this problem is not really worth dealing with it as "in general" the user will stay on your app.

But, the user did something, you're trying to get informations on the web, information is ready, and you have to show it when the user resume the app... the main word is "resume".

You must gather the data you needed into a variable (and if you can, a parcelable or primitive variable), and then, override your "onResume" or "onPostResume"(for activities) functions in the following way.

public void onResume/onPostResume() {
    super.onResume/onPostResume();
    if(someTreatmentIsPending) {
        /*do what you need to do with your variable here : fragment 
        transactions, dialog showing...*/
    }
}

Additional informations : This topic and especially @jed answer, and @pjv, @Sufian comments to it. This blog in order to understand why the bug occurs, and why proposed/accepted answers work.

Last word : Just in case you wonder "why using a service is better than asyncTask". For what i understood, that's not really better. The main difference is that using service properly allow you to register/unregister handlers when your activity is paused/resumed. Therefore, you always get your answers when your activity is active, preventing the bug to occurs.

Notice that's not because the bug does not occurs that you are safe. If you made changes directly on your views, there is no fragmentTransactions involved, therefore, no guarantee that the change will be retained and recreated when the app is recreated, resumed, relaunched, or anything else.

like image 141
Feuby Avatar answered Sep 28 '22 03:09

Feuby