I recently converted my app from an activity based app to a fragment based app. It's a score keeping app, and I was easily able to save and restore score when it was an activity. However, that doesn't seem to be working as a fragment. Here's my code:
@Override
public void onSaveInstanceState(Bundle savedInstanceState){
super.onSaveInstanceState(savedInstanceState);
if(t!=null&&flag==1){
savedInstanceState.putInt("time", t.getTimeLeft());
} else {
savedInstanceState.putInt("time", 0);
}
savedInstanceState.putIntArray("score_array", points);
savedInstanceState.putIntArray("position_array", spinnerPosition);
savedInstanceState.putBooleanArray("checked_array", shouldBeChecked);
flag = 0;
Log.d("MyApp", "savingState");
}
@Override
public void onActivityCreated(Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
Log.d("MyApp", "onActivityCreated");
try {
int timeLeft = savedInstanceState.getInt("time");
points = savedInstanceState.getIntArray("score_array").clone();
spinnerPosition = savedInstanceState.getIntArray("position_array").clone();
shouldBeChecked = savedInstanceState.getBooleanArray("checked_array").clone();
((BaseAdapter) ((ListView)getView().findViewById(R.id.missionList)).getAdapter()).notifyDataSetChanged();
if(timeLeft!=0){
flag=1;
this.getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
t = new TimerClass(timeLeft*1000, 1000);
t.setViews((TextView)getView().findViewById(R.id.minuteView), (TextView)getView().findViewById(R.id.tenSecondView), (TextView)getView().findViewById(R.id.secondView), (Button)getView().findViewById(R.id.start_button));
((Button)getView().findViewById(R.id.start_button)).setText(R.string.stop);
t.start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
I used this exact same code successfully on an activity in onRestoreInstanceState
rather than onActivityCreated
and without the try/catch. The problem is I'm getting null pointer errors an time I try and pull something from the bundle. I can see saving state in the log, and then onActivityCreated, but onActivityCreated doesn't seem to be getting the stuff put in the bundle by onSavedInstanceState. I just get a null pointer on every line that calls savedInstanceState.getAnything()
. However, from my reading, onCreate
, onCreateView
, and onActivityCreated
all use the same bundle. I have tried moving the code to the other two with no luck.
For anyone who needs a better answer:
Always test for if(savedInstanceState!=null)
before accessing it, to avoid null pointer errors.
Also, be aware that onSaveInstanceState() won't be able to save your data in all cases when your fragment is destroyed.
Particularly if your Fragment is pushed onto the back stack, and the device is rotated. In this case, only onDestoryView() gets called when your Fragment is pushed onto the back stack, so when onSaveInstanceState() runs during device rotation, it won't be able to save any data from your Views because they were all destroyed earlier.
See the following thread for a work-around. I think it's useful for everybody developing with Fragments. Especially DroidT's answer: https://stackoverflow.com/a/19744402/2517350
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With