commitAllowingStateLoss() and commit() fragment

前端 未结 5 956
陌清茗
陌清茗 2021-02-04 03:47

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 cr

5条回答
  •  轻奢々
    轻奢々 (楼主)
    2021-02-04 03:59

    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.

提交回复
热议问题