Part One: now solved in edit
I'm making a WebView in a fragment that will reload the currently viewed page and maintain its history when the parent activity restarts. Although I've found one way to reload the currently viewed page (the second solution below), I'm still looking for a way to maintain the history.
Solutions I've tried:
Android webView saveState : I put the restoreState bit in onCreateView. Nothing happened, neither url nor history were retained.
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
l = inflater.inflate(R.layout.fragment_page_viewer, container, false);
webView = l.findViewById(R.id.webView);
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebViewClient(myWebClient);
if(savedInstanceState == null) {
webView.loadUrl(url);
}else{
webView.restoreState(savedInstanceState);
}
return l;
}
@Override
public void onSaveInstanceState(Bundle outState){
webView.saveState(outState);
super.onSaveInstanceState(outState);
}
Part Two: Unable to convert WebBackForwardList back from json
Webview is not restoring the state after it was killed by the user : I tried this as a rather bulky work-around. Although this method was great for retaining the current webpage, I couldn't retain the WebBackForwardList with it. I tried turning the WebBackForwardList into a json file via gson to put into the SharedPreferences, but when I tried to convert the json back to a WebBackForwardList, I got:
java.lang.RuntimeException: Failed to invoke public android.webkit.WebBackForwardList() with no args
Not to mention, I still have no idea how I would have assigned the retained WebBackForwardList to the WebView without basically rewriting goBack() and goForward(), and it seems like there really ought to be a simpler way...
@Override
public void onStart() {
super.onStart();
if(webView != null){
Context context = getContext();
SharedPreferences prefs = context.getApplicationContext().getSharedPreferences(context.getPackageName(), Activity.MODE_PRIVATE);
String s = prefs.getString(URL_KEY, "");
if (!s.equals(null))
url = s;
webView.loadUrl(url);
gson = new Gson();
json = prefs.getString(HISTORY_KEY, "");
if(!json.equals(null)){
WebBackForwardList history = gson.fromJson(json, WebBackForwardList.class); //LINE ERROR MESSAGE POINTS TO
String log = history.getItemAtIndex(history.getCurrentIndex()).getUrl();
Log.d("history", log);
}
}
}
@Override
public void onStop() {
super.onStop();
Context context = getContext();
SharedPreferences prefs = context.getApplicationContext().getSharedPreferences(context.getPackageName(), Activity.MODE_PRIVATE);
SharedPreferences.Editor edit = prefs.edit();
gson = new Gson();
json = gson.toJson(webView.copyBackForwardList());
edit.putString(HISTORY_KEY, json);
edit.putString(URL_KEY, webView.getUrl());
edit.commit();
}
EDIT:
- The problem with attempted solution number one was an error in the activity code.
I had written
if(fragmentVar == null){...}
, which is always false when the activity restarts, because the variable isn't yet assigned inside the activity. Instead I needed to write
if(fragmentManager.findFragmentById(R.id.page_control) == null){...}
because the fragment manager is the object that retains the fragment.
- However, I'm still stumped by why I was unable to convert the WebBackForwardList from a json.