Saving object in android in onSaveInstanceState() - android

This is a puzzle app. I have a class of Puzzle that contains the object itself and business logics. In onCreate, I created the object itself, I need to save the instance. Is it a good idea to save the same object I created in onCreate in onSaveInstanceState()? If so, what is the best way to do it? Otherwise, should I save the variables of the object Puzzle in onSaveInstanceState()?
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Read in the arrays
String[] targetWords = getResources().getStringArray(R.array.target_words);
String[] okWords = getResources().getStringArray(R.array.acceptable_words);
// TODO: Now we always create a new puzzle when the Activity is created. You
// will need to restore the existing activity if the Framework has destroyed
// and recreated it.
newPuzzle = new Puzzle(targetWords, okWords);
for (int i = 0; i < newPuzzle.getGuessCount(); i++) {
displayResult(i);
}
}
// save the puzzle obj?
#Override
public void onSaveInstanceState(Bundle outState){
super.onSaveInstanceState(outState);
}

Make your Puzzle Object Parcelable or Serializable, then save it in:
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putSerializable("puzzleObj", newPuzzle);
}
You can retrieve it in onCreate()
if (savedInstanceState != null) {
newPuzzle = (Puzzle) savedInstanceState.getSerializable("puzzleObj");
}

Related

savedInstanceState is always null value in onCreate

This is my onCreate method in a class which is subclass of fragment
static int counter = 0;
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
if(savedInstanceState == null) { //made for first time
Log.d("came in", "Came in");
counter = 0;
} else {
counter = savedInstanceState.getInt("counter", 0);
}
}
this is my savedInstanceState method
#Override
public void onSaveInstanceState(Bundle outState){
super.onSaveInstanceState(outState);
Log.d("hi there", ""+counter); // this is printing hi there 3
outState.putInt("counter", counter);//key value pair
}
but in onCreate method savedInstanceState is always null and printing came in.
Override protected void onRestoreInstanceState(Bundle savedInstanceState) and see if you can get your values there.
Try to save your value in your fragment host activity(Activity in which your fragment is defined). From host activity, you have to extract that value and access it in your fragment subclass.
try change you method onSaveInstanceState to:
#Override
public void onSaveInstanceState(Bundle outState){
Log.d("hi there", ""+counter); // this is printing hi there 3
outState.putInt("counter", counter);//key value pair
super.onSaveInstanceState(outState); // call super after put int
}

Saving the state of my App through rotation

I am building a memory game app for a java class and i need to save which words are displayed through rotation of the device...the widgets that need to be saved and passed to the new onCreate() method are button widgets that i used setText to display the words that are being shown....can i save and pass the entire state of the application...here is my code that is obviously not working and i was hoping i could get some insight...thanks...here is my code..
private Bundle myBundle = new Bundle();
.....
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_eight);
if(savedInstanceState != null) {
savedInstanceState = myBundle;
}
......
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
myBundle = savedInstanceState;
}
You got the semantics of using the Bundle backwards. You don't ever want to save the Bundle (or overwrite it). Just use it to serialize your own state variables into it and out of it. For example, if you want to preserve two integer variables and a string between a rotation (such that you can re-initialize the view with these members later), you could do the following:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_eight);
if(savedInstanceState != null) {
// Restore our member variables that represent activity state right here from the passed in Bundle.
_x = savedInstanceState.getInt("MyApp.X", 0);
_y = savedInstanceState.getInt("MyApp.Y", 0);
_name = savedInstanceState.getString("MyApp.NAME", "player");
// not shown - initializing the view elements with the initialized member variables.
}
......
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// save our activity state by adding our member variables that represent activity state into the Bundle.
savedInstanceState.putInt("MyApp.X", _x);
savedInstanceState.putInt("MyApp.Y", _y);
savedInstanceState.putString("MyApp.NAME", _name);
// call the parent method *after* you have saved your state
super.onSaveInstanceState(savedInstanceState);
}
Bundle also supports arrays of simple types.
In method onSaveInstanceState add values which you want to save like below
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putString("key","your string here");
}
and inside oncreate
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if( savedInstanceState != null ) {
System.out.println(savedInstanceState .getString("key"));
}
}

Is it save to overrwrite the savedInstanceState bundle after passing it up?

I have the following (to avoid checking if a fragment is being created newly or just being recreated)
#Override public void onActivityCreated(Bundle args) {
super.onActivityCreated(args);
if (this.getArguments() != null) args = this.getArguments();
// rest of fragment loading goes here
}
Not sure what you are trying to do never seen budle values being overwritten.
If you want some values to be availbale inside fragment pass those values to activity and inside fragment call getActivity().getIntent().getExtra(
Otherwise have a look at code below if want save some fragment data if fragment is destroyed
Inside fragment in onCreate method check if savedInstanceState is null or not
#Override
public void onCreate(Bundle savedInstanceState) {
if (savedInstanceState != null) {
//fragment recreated
}
}
Save data as follows
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (jsonObject != null) {
outState.putString(Constants.JSON, jsonObject.toString());
}
}

saving ArrayList in the bundle savedInstanceState

the ArrayList is defined on class level.
these are my savedInstance methods:
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putStringArrayList("savedList", list);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
list=savedInstanceState.getStringArrayList("savedList");
}
but still, when i change orientation the ArrayList is blank
When you use onRestoreInstanceState() to restore state, its called after onStart() so you update your list with the saved state after you define your adapter. Your best option is to restore the list in onCreate() the same way you do it on onRestoreInstanceState(). You can also redefine the adapter or call notifyDataSetChanged().
TextView textviewname;
String textname;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//declare the ui like this
textviewname = (TextView) findViewById(R.id.textviewid);
if(savedInstanceState==null){
//the first time the activity was created
//do the normal flow of the code
//Example:getting the intent data for(savedList)or processing it
Intent i = getIntent();
textname = i.getStringExtra("savetext");
//or textname="name_data";
}else{
//this is called when orientation change occur
//get the savedata
list=savedInstanceState.getStringArrayList("savedList");
textname=savedInstanceState.getString("savetext");
}
textviewname.setText(textname);
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//saving data when orientation change trigger
//saving data before ondestroy happens
//onSaveInstanceState is called before going to another activity or orientation change
outState.putStringArrayList("savedList", list);
outState.putString("savetext", textname);
//all imnportant data saved and can be restored
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
//this is only called after ondestroy-> oncreate occur
list=savedInstanceState.getStringArrayList("savedList");
textname=savedInstanceState.getString("savetext");
//oncreate->onSaveInstanceState->ondestroy->oncreate->onRestoreInstanceState
}
try to use
list.addAll(savedInstanceState.getStringArrayList("savedList"));
instead
list=savedInstanceState.getStringArrayList("savedList");

how to store values and retrieve it when the orientation changes?

I have checked many posts, and as per that I have done coding for the orientation change. When orientation changes, the problem is I am not able to retrieve the entered values inside TextViews. Can anyone plz tell where did I go wrong?
Coding:
In manifest file for the corresponding activity I added:
android:configChanges="orientation|keyboardHidden"
In activity, I added the following methods:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.home_screen);
//Initialized the widgets
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
//have written separate layout files for portrait and landscape
setContentView(R.layout.home_screen);
//Initialized the widgets again
retrieveSavedState(); //sets the TextViews again
}
#Override
protected void onPause() {
super.onPause();
saveState(); //save the TextView values
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
saveState();
}
#Override
protected void onResume() {
super.onResume();
retrieveSavedState();
}
#Override
public Object onRetainNonConfigurationInstance()
{
final MyDataObject data = collectMyLoadedData();
return data;
}
the above method can be used to save any object to save data...
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final MyDataObject data = (MyDataObject) getLastNonConfigurationInstance();
if (data == null) {
data = loadMyData();
}
...
}
and u can retreive that object in the onCreate() which will we called when orientation changes.. after reading data from that object you can use it where ever you want..
http://developer.android.com/guide/topics/resources/runtime-changes.html
http://developer.android.com/guide/topics/resources/runtime-changes.html
other mechanisms are also there but this is the best way for my knowledge.. you can also use shared preferences to store and retrieve data...
http://saigeethamn.blogspot.com/2009/10/shared-preferences-android-developer.html

Categories

Resources