Tom Shen Tom Shen - 3 months ago 28
Android Question

What is the best way to store Date in savedInstanceState?

I am using the onSaveInstanceState method to store and retrieve local variables inside a fragment.
I have the following code (simplified) in one of my fragments :

private final SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy - HH:mm");
private Date myDate;

public Date getDate() { return myDate; }

public void setDate(Date date) { this.myDate = date; }

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.main, container, false);

TextView tvDate = (TextView) rootView.findViewById(R.id.textview_date);

if (savedInstanceState != null) {
try {
myDate = dateFormat.parse(savedInstance.State.getString("DATE"));
catch (ParseException e) {
}
}

//myDate is being set by a different fragment using the setDate method

if (tvDate != null)
tvDate.setText(dateFormat.format(myDate));

return rootView;
}

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putString("DATE", dateFormat.format(myDate));
}


This way I can store and retrieve the date value when my view gets destroyed and recreated, by rotating the screen for example, which is was the main problem.
This works, but I can tell this isn't efficient. If I store more variables like this, the view creation is taking much longer (a few seconds to load for 10 variables containing strings and booleans).

I was wondering if there is a better way to do this. Any suggestion is welcome.

Answer

Your code does not seem to cause performance issues and is the normal and efficient way to store your state on Android. I've added some comments/adjustments to your code below however which might tackle other errors or could speed things up.

    private static final String STATE_DATE = "state:date";

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, e Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.main, container, false);

        TextView tvDate = (TextView) rootView.findViewById(R.id.textview_date);

        // Check if the savedInstanceSTate contains the date String key.
        if (savedInstanceState != null
                && savedInstanceState.containsKey(STATE_DATE)) {

            try {
                // Consider doing complex tasks like parsing etc. in the background.
                // Parsing a date shouldn't be the issue here but doing many things like this may 
                // be the cause of the performance issue. 
                myDate = dateFormat.parse(savedInstanceState.getString(STATE_DATE));
                catch(ParseException e){
                }
            }

            //myDate is being set by a different fragment using the setDate method

            if (tvDate != null)
                tvDate.setText(dateFormat.format(myDate));

            return rootView;

        }
    }

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        super.onSaveInstanceState(savedInstanceState);
        // Remove the date formatter here. Try to format your date immediately when storing it in the variable.
        // When restoring your date from your savedInstanceState you're already formatting it.
        savedInstanceState.putString(STATE_DATE, myDate);
    }