Android: onSaveInstanceState not being called from activity

AndroidAndroid Activity

Android Problem Overview


I have an Activity A which calls Activity B. In Activity B, when i click on a button, finish() is called, which in turn calls onDestroy() of Activity B and returns to activity A.

According to android documentation, Before onDestroy is called, onSaveInstanceState(Bundle bundle) will be called, where i do the following.

@Override
	public void onSaveInstanceState(Bundle outState) {
		
		super.onSaveInstanceState(outState);
		System.out.println("Saving webview state");
		Log.d(TAG, "In onsave");
		wv.saveState(outState);

	}

and the next time Activity B is started from Activity A,

in the oncreate(), i do the following:

onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);

if(savedInstanceState != null){
//restore webview
}else {
// code
}
}

However, before calling onDestroy in Activity B, The onSaveInstanceState method is never called. any help on this will be greatly appreciated.

EDIT: if this is not possible. Please let me know if there is a way to store webview state

Android Solutions


Solution 1 - Android

I had a similar situation. It was clearly a dev bug. I've overridden the wrong method:

public void onSaveInstanceState(Bundle outState, 
                                PersistableBundle outPersistentState)

Instead a correct one:

protected void onSaveInstanceState(Bundle outState)

Solution 2 - Android

Please notice that onRestoreInstanceState() is called when activity is recreated but only if:

it was killed by the OS. "Such situation happen when:

  • orientation of the device changes (your activity is destroyed and recreated)
  • there is another activity in front of yours and at some point the OS kills your activity in order to free memory (for example). Next time when you start your activity onRestoreInstanceState() will be called."

So if you are in your activity and you hit Back button on the device, your activity is finish()ed and next time you start your app it is started again (it sounds like re-created, isn't it?) but this time without saved state because you intentionally exited it when you hit Back button.

Solution 3 - Android

See the doc here: http://developer.android.com/reference/android/app/Activity.html

> Note that it is important to save persistent data in onPause() > instead of onSaveInstanceState(Bundle) because the latter is not > part of the lifecycle callbacks, so will not be called in every > situation as described in its documentation.

The documentation of onSaveInstanceState method says,

> Do not confuse this method with activity lifecycle callbacks such as > onPause(), which is always called when an activity is being placed > in the background or on its way to destruction, or onStop() which is > called before destruction. One example of when onPause() and > onStop() is called and not this method is when a user navigates back > from activity B to activity A: there is no need to call > onSaveInstanceState(Bundle) on B because that particular instance > will never be restored, so the system avoids calling it. An example > when onPause() is called and not onSaveInstanceState(Bundle) is > when activity B is launched in front of activity A: the system may > avoid calling onSaveInstanceState(Bundle) on activity A if it isn't > killed during the lifetime of B since the state of the user interface > of A will stay intact.

try this:

@Override
public void onPause(){
   System.out.println("Saving webview state");
    Log.d(TAG, "In onsave");
    wv.saveState(outState);
    super.onPause();

}

and
@Override
 public void onResume(){
     //restore webview
 }

I am not sure what is the purpose of that if statement, but try this and see what happens.

Solution 4 - Android

Eventually you're going to have to write the the back/history to persistent storage. In the case of the device being shut down as one example, as well as avoiding a contrived (in my opinion) example where you call onSaveInstanceState in onPause (what you'll need to do to get the bundle you want passed into onRestoreInstanceState which you can then pass into restoreState).

Therefore, besides reconsidering your design (if the user closed your application and you're not making a browser, do they really want to keep the same history?), you should look up SharedPreferences and how to use them.

Unfortunately you cannot put a bundle in shared preferences, nor would I recommend trying to write the bundle via Parcelable (it's only meant for IPC, not persistent storage). But what you can do is store all the primitives that the bundle stores. This might be contrived too, but it seems to me the only way to get permanent storage.

And then rebuild your bundle via the primitives stored in SharedPreferences, and pass that into restoreState(). You can check the Android source code to see what webView.saveState() actually does (I looked up the 2.1 code and it seems to write a int, a serializeable object, and then another bundle for the SSL cert. The SSL cert bundle itself is just four integers). Off the top of my head, I'd just write all the primitives you can, and then store the location (string) of the local file you write the serialized data too.

Even if you have some ordered collection of the entire BackForward list, I'm not sure how to translate that into the goBack() and goForward() using those values (there's a protected method that's involved in adding items to the list but you can't access that). UNLESS you do use restoreState(), which is why we're going to all the work to rebuild the bundle correctly.

Seriously though, unless my search skills are abysmal (entirely possible), storing the WebView history in places beyond where saveInstanceState/restoreInstanceState can do your work for you doesn't seem to be a problem a lot of people have run into. I.e. not a lot of people are trying to persist the WebView history when the user explicitly closes their application, so you have to ask yourself why are YOU doing this?

Apologies if there is a really easy way to persistently store this information and reload into a WebView btw!

Solution 5 - Android

for call onSaveInstance method please just use

public void onSaveInstanceState(Bundle outState)

for save a value not need use

public void onSaveInstanceState(@NonNull Bundle outState, @NonNull PersistableBundle outPersistentState)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBharathView Question on Stackoverflow
Solution 1 - AndroidPaweł SzczurView Answer on Stackoverflow
Solution 2 - AndroidMarcin S.View Answer on Stackoverflow
Solution 3 - AndroidfangmobileView Answer on Stackoverflow
Solution 4 - Androidaamit915View Answer on Stackoverflow
Solution 5 - Androidali karimifardView Answer on Stackoverflow