Loader is not retained after starting new activity, changing orientation in new activity and pressing back button

StackOverflow https://stackoverflow.com/questions/16529478

Вопрос

I been running into an issue with loaders lately. I created a small project that reproduces the issue https://github.com/solcott/loaders-orientation-change

I have a simple Activity that adds a fragment

public class MainActivity extends Activity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Fragment mainFragment = getFragmentManager().findFragmentById(R.id.main_fragment);
    if(mainFragment == null){
        Log.w(getClass().getSimpleName(), "creating new Fragment");
        mainFragment = new MainFragment();
        getFragmentManager().beginTransaction().add(R.id.main_fragment, mainFragment).commit();
    }
  }
}

In my fragment I start a Loader that just returns an integer that is displayed on the screen. There is also a button that starts a new Activity:

public class MainFragment extends Fragment implements LoaderCallbacks<Integer> {

private static int NEXT_VAL = 0;

TextView text1;

Button button1;

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    getLoaderManager().initLoader(1, null, this);
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    return inflater.inflate(R.layout.fragment_main, container, false);
}

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    text1 = (TextView) view.findViewById(android.R.id.text1);
    button1 = (Button) view.findViewById(android.R.id.button1);
    button1.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            startActivity(new Intent(getActivity(), NextActivity.class));
        }
    });
}

@Override
public Loader<Integer> onCreateLoader(int id, Bundle args) {
    AsyncTaskLoader<Integer> loader = new AsyncTaskLoader<Integer>(
            getActivity()) {

        @Override
        public Integer loadInBackground() {
            return NEXT_VAL++;
        }
    };
    loader.forceLoad();
    return loader;
}

@Override
public void onLoadFinished(Loader<Integer> loader, Integer data) {
    text1.setText(data.toString());
}

@Override
public void onLoaderReset(Loader<Integer> loader) {
    // TODO Auto-generated method stub

}

}

Up to this point everything works fine I can change the orientation and the integer that is displayed doesn't change. I can even start the new activity and then hit the back button and the integer displayed doesn't change.

However, when I navigate to the new Activity, change orientation and press the back button the integer is incremented. I would expect it to behave the same way that it did without the orientation change.

Calling setRetainInstance(true) in Fragment.onCreate() make it even worse. onLoadComplete is never called and the integer is not displayed at all.

Has anyone else run into this issue and found a workaround?

Это было полезно?

Решение

Same question as asked here: Loader unable to retain itself during certain configuration change

This is a damn annoying problem with AsyncTask loaders. Although a solution is proposed in that thread, I think the general consensus is to avoid AsyncTaskLoaders.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top