advantej
advantej

Reputation: 20325

Why is my loader destroyed?

I have a Fragment which uses a Loader. The Fragment implements LoaderManager.LoaderCallbacks. In the onCreate() of the fragment I do a setRetainInstance(true) so that the Fragment is not destroyed across configuration changes like orientation change. This works as expected and the onDestroy() for the fragment is not called. However, my loader is destroyed when I rotate the device. Each time I rotate the device a new Loader is created. I checked the memory dump and verified this.

  1. Why is this happening
  2. How can I avoid this ?

EDIT: To avoid confusion : The local variable loader is not relevant here. It is just to check if my previously created loader exists or not. Even with the updated code below (removed the local variable), the loader is destroyed.

Here is some relevant code:

    public class MyFragment extends Fragment implements LoaderManager.LoaderCallbacks<Object> {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true); //Don't destroy fragment across orientation change
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        Log.d(TAG, "onActivityCreated, myTid : " + android.os.Process.myTid());

        mLoaderManager = getLoaderManager();
        mLoaderManager.initLoader(MY_LOADER, null, this);
    }

    @Override
    public Loader<Object> onCreateLoader(int i, Bundle bundle) {
        Log.d(TAG, "onCreateLoader, myTid : " + android.os.Process.myTid());
        return new MyLoader(getActivity().getApplicationContext());
    }

   @Override
    public void onLoaderReset(Loader<Object> objectLoader) {
        Log.d(TAG, "onLoaderReset, myTid : " + android.os.Process.myTid());

        mHandler.post(new Runnable() {
            @Override
            public void run() {
                if (mTxtSomeTxt != null) {
                    mTxtSomeTxt.setText("");
                }
            }
        });
    }

    }

Upvotes: 2

Views: 1280

Answers (1)

kjones
kjones

Reputation: 5823

A little bit late to the party...

For retained fragments you need to save the loader returned from initLoader(...) and then when a configuration change occurs return the original loader.

private Loader<Object> myLoader;

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    Log.d(TAG, "onActivityCreated, myTid : " + android.os.Process.myTid());

    mLoaderManager = getLoaderManager();
    myLoader = mLoaderManager.initLoader(MY_LOADER, null, this);
}

@Override
public Loader<Object> onCreateLoader(int i, Bundle bundle) {
    Log.d(TAG, "onCreateLoader, myTid : " + android.os.Process.myTid());

    // Handle loader creation on retrained fragments
    if (myLoader != null)  {
        return myLoader;
    }

    return new MyLoader(getActivity().getApplicationContext());
}

Upvotes: 1

Related Questions