Harel Moshe
Harel Moshe

Reputation: 454

AsyncTask, progress and fragments

I have a activity that show a progress-bar fragment, loads-data and then shows it in a new fragment, after hiding the progress-bar fragment.

I ran into the infamous onPostExecute() / configuration-change problem, and after reading numerous posts about possible solutions, i figured non of them deals with switching fragments in onPostExecute() - which can also be potentially hazardous since it might throw IllegalStateException while trying tho commit a fragment transaction after the activity has saved it's state.

That's the piece of relevant code:

public class MyActivity extends FragmentActivity implements {

    class LoadListTask extends AsyncTask<Void, Void, MyListItem> {

        @Override
        protected void onPreExecute() {
            showProgressBar();
        }

        @Override
        protected Response doInBackground(Void... params) {
            //
            // ... web call
            //
            return new List<MyListItem>;
        }

        protected void onPostExecute(List<MyListItem> result) {
            if (result != null) {
                hideProgressBar();
                showList(result);
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(...);
        new LoadListTask().execute(session);
    }

    public void showProgressBar() {
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager
                .beginTransaction();

        fragmentTransaction.replace(R.id.placeholder,
                mProgressBarFragment).commit();
        fragmentManager.executePendingTransactions();
    }

    private void hideProgressBar() {
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager
                .beginTransaction();
        fragmentTransaction.remove(mProgressBarFragment)
                .commit();
        fragmentManager.executePendingTransactions();
    }

    private void showList(List<ListItem> list) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager
                .beginTransaction();

        Fragment frg = FacebookFriendPickerFragment
                .newInstance(friendsArrObj);
        fragmentTransaction.replace(R.id.friendPickerPlaceholder, frg)
                .commit();
        fragmentManager.executePendingTransactions();
    }
}

I'm starting to think that having a fragment that merely show progress complicates things, but i really do want to stick to fragments - so is there any way to "synchronize" the fragment-transaction so it would happen in a reasonable phase of the activity life-cycle, and avoid the AsyncTask/config-change issue?

Upvotes: 1

Views: 1707

Answers (1)

Volodymyr Yatsykiv
Volodymyr Yatsykiv

Reputation: 3211

you need to put this code to your fragment:

// Retain this fragment across configuration changes.
setRetainInstance(true);

more about handling configuration changes with fragments you can read in this tutorial:

http://www.androiddesignpatterns.com/2013/04/retaining-objects-across-config-changes.html

Hope, I help you.

Upvotes: 1

Related Questions