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?