How to effectively retain User’s valuable resource (Data) in Android
Friends, In Android either user may be interacting with normal Activity or any fragment that is associated with Activity. Some real time situation like Rotation of device (orientation Changes), Other configuration changes include the change of a language, addition or removal of an input device (such as a keyboard), or when a device changes dock status (when a device is plugged into/unplugged from a car or desk dock) may cause activity to get destroyed and initialized again (in short, Activity will undergo all the states of its life cycle). Due to this user may lose his / her resource (data) when interacting with the device.
Android provides number of remedies to solve this issues, I will discuss my ideas in two divisions.
1) Data retention in Activity
For Activity you may do this in two ways,
a) using onSaveInstanceState() — this call back method of activity is called between onPause() and onStop() methods of an Activity.
screen 1
This method takes a parameter of Bundle type, which is nothing but similar to HashMap of Java for storing Key-Values pairs.
Take an example, for demonstration I will store some value and display before and after orientation of device. I took normal java.util.Calendar class and display seconds in Toast widget.
screen 2
You may note from following screen shots that Toast prints different values of seconds on Orientation change of screen, this is due to the fact that seconds keeps on incrementing. To store previous value I took help of onSavedInstance() method
screen 3
on changing orientation
screen 4
Using onSavedInstanceState()
screen 5
I made a key name “audhilKey” to hold the value startTime. Again at onCreate method we need to check for null values before retriving values from bundle type.
screen 6
on Changing orientation
screen 7
I hope you may understand from the screen shots.
b) using onRestoreInstanceState() — it is called between onStart() and onResume() method of an activity
As discussed before, I would like to display same data (seconds) on Toast in-spite of changes in orientation
You may note that there is no need of onCreate() method too, since this call back is executed after onCreate() of an activity. Hence I made the result to be shown at onResume() method.
- As like before, I made instance of Calendar
- and stored its value into Bundle with key named as “audhilKey” and value of Calendar Instance
- I made use of onRestoreInstanceState() by assigning the value from Bundle to Calendar Instance (startTime)
- Again at onResume() I made a toast to display the same result
You may get same result as of like my 6th and 7th screen shots.
These datatypes can be retrieved from Bundles, for usage
Allowed Bundle Value Typesbooleanboolean[ ]Bundle (yes — store a Bundle in a Bundle)bytebyte[ ]charchar[ ]CharSequenceCharSequence[ ]ArrayListdoubledouble[ ]floatfloat[ ]intint [ ]ArrayList<Integer>longlong[ ]Serializableshortshort[ ]SparseArray — a map of integer to Object and is more efficient than a HashMap. Used more internally by Android (see below)StringString[ ]ArrayList<String>
2) Data retention in Fragments
Fragments are like sub activities and has their own life cycle. However data persistent is similar to activity.
a) As like activty fragments too has onSaveInstanceState() method, with same functionality. It is called between onPause() and onStop() methods of fragments
Taking Same example,
public class MainActivity extends Activity {
Calendar startTime = Calendar.getInstance();
}
and onSaveInstanceState()
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// putting startTime into outstate Bundle (hashmap) with key named audhilKey
outState.putSerializable("audhilKey", startTime);
}
Finally you can use any method of fragments which takes parameter Bundle savedInstance such as onCreate, onCreateView, or onActivityCreated .
I took onCreateView()
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.home, container, false);
if ((savedInstanceState != null) && (savedInstanceState.getSerializable("audhilKey") != null))
startTime = (Calendar) savedInstanceState.get("audhilKey"); // it is equivalent to startTime = (Calendar)savedInstanceState.getSerializable("audhilKey");
Toast.makeText(getApplicationContext(), startTime.get(Calendar.SECOND) + "", Toast.LENGTH_LONG).show();
return rootView;
}
b) another way of retaining data using fragment is that making our fragment to retain itself as though its activity gets recreated or changes it state. Hence life cycle of a fragment gets modified as like below
This can be achieved at onCreate() method of fragment as follows
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setRetainInstance(true);
}
As a result my fragment does not get destroyed and recreated on orientation change of device etc …
For more browse part 1 and part 2 to get beautiful explanation …
Enjoy … !