Android: onSaveInstanceState not being called from activity
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)
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 ofonSaveInstanceState(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, oronStop()
which is called before destruction. One example of whenonPause()
andonStop()
is called and not this method is when a user navigates back from activity B to activity A: there is no need to callonSaveInstanceState(Bundle)
on B because that particular instance will never be restored, so the system avoids calling it. An example whenonPause()
is called and notonSaveInstanceState(Bundle)
is when activity B is launched in front of activity A: the system may avoid callingonSaveInstanceState(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.
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!
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.