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
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.
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 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.
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!