9

When I backup & restore the state of my WebView, I receive this message: the webpage at x Address might be temporarily down or may have moved permanently to a new web address.

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    super.onSaveInstanceState(savedInstanceState);
    webViewShowPoll.saveState(savedInstanceState);                                    
}

@Override
public void onRestoreInstanceState(Bundle outState) {
  super.onRestoreInstanceState(outState);
    webViewShowPoll.restoreState(outState);
}

Androidmanifest.xml

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.SET_DEBUG_APP"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />    
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />    


    <activity
        android:name="com.omid.epoll.mobile.Poll"
        android:launchMode="singleInstance"
        android:label="@string/title_activity_poll" 
        android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen">
    </activity>
ricardopereira
  • 11,118
  • 5
  • 63
  • 81
Amir
  • 782
  • 1
  • 9
  • 19

5 Answers5

3

restoreState was never reliable. That's perhaps why the documentation now says this.

If it is called after this WebView has had a chance to build state (load pages, create a back/forward list, etc.) there may be undesirable side-effects. Please note that this method no longer restores the display data for this WebView.

And the corresponding entry for saveState() speaks thus:

Please note that this method no longer stores the display data for this WebView.

what you really should do inside the onCreate method is to call webView.loadUrl() if you want to display the last visited url, please see this answer:

If you are concerned about the webview reloading on orientation change etc.

you can set your Activity to handle the orientation and keyboardHidden changes, and then just leave the WebView alone

Community
  • 1
  • 1
e4c5
  • 52,766
  • 11
  • 101
  • 134
  • 3
    This is an overly paranoid reading of the docs. Losing the "display data" is fine. All that means is that the page reloads when the flip occurs. The first warning simply boils down to: do the restoreState before you do anything else to the WebView. The current page, and history are saved and restored; so you don't need to call webView.loadUrl() after restoreState: the display data for saved page will be reloaded. No problem. restoreState is perfectly reliable as long as you do it first. – Robin Davies Sep 27 '19 at 18:54
  • 1
    Now that google is promoting the "Single Activity" apps, I'm not sure your last sentence is usable... I've been trying to keep a webView from reloading on orientation change, and I still cannot figure it out. – Lucas P. Oct 07 '19 at 13:02
  • please note that this answer is more than 4 years old. Please feel free to add your own answer that's relevant to todays context. – e4c5 Oct 07 '19 at 13:05
3

It seems it is a very old question. I make a lot of search and I tested different solutions. This was the first article what I found. So I thougth I write my own solution

In 2022 I have a current solution (Kotlin):

In manifest you should set this in the activity where you want to use the WebView.saveState + WebView.restoreState

<activity
<!-- ... -->
android:configChanges="orientation|screenSize">

And in the activity you should use your own boundle:

class MyActivityContainsWebView : AppCompatActivity() {
private var savedInstanceState: Bundle? = null
// ...
override fun onCreate(savedInstanceState: Bundle?) {
//..
    this.savedInstanceState = savedInstanceState
    if (savedInstanceState != null)
      webView.restoreState(savedInstanceState.getBundle("webViewState")!!);
//..
}

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    val bundle = Bundle()
    webView.saveState(bundle)
    outState.putBundle("webViewState", bundle)
}

override fun onRestoreInstanceState(savedInstanceState: Bundle) {
    super.onRestoreInstanceState(savedInstanceState)
    webView.restoreState(savedInstanceState)

}
  • why in "onRestoreInstanceState" you directly called "webView.restoreState(savedInstanceState)" instead of "webView.restoreState(savedInstanceState.getBundle("webViewState"))" like in "onCreate"? – programmer dreamer Jun 26 '23 at 08:53
2
 if (isInternetPresent) {
        // Internet Connection is Present
        // make HTTP requests
        // showAlertDialog(HomeScreen.this, "Internet Connection",
        // "You have internet connection", true);

        webviewbrowse.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
        webviewAds.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
        webviewbrowse.loadUrl("http://www.example.com");
    } else {
        // Internet connection is not present
        // Ask user to connect to Internet
        webviewbrowse.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
        webviewAds.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
        webviewbrowse.loadUrl("http://example.com");
        showAlertDialog(HomeScreen.this, "internet doesn't connect",
                " please connect to internet", false);
    }
Taylan Aydinli
  • 4,333
  • 15
  • 39
  • 33
Mohammed Saleem
  • 568
  • 5
  • 20
-1
     binding.webView.setWebViewClient(new WebViewClient() {
         public boolean shouldOverrideUrlLoading(WebView view, String url) {
             view.loadUrl(url);
             return true;
         }

         @Override
         public void onPageStarted(WebView view, String url, Bitmap favicon) {
             super.onPageStarted(view, url, favicon);
         }

         @Override
         public void onPageFinished(WebView view, String url) {
             super.onPageFinished(view, url);
         }
     }
    );

    binding.webView.getSettings().setJavaScriptEnabled(true);
    binding.webView.getSettings().setBuiltInZoomControls(true);
    binding.webView.getSettings().setDisplayZoomControls(false);
    binding.webView.getSettings().setAppCacheMaxSize( 5 * 1024 * 1024 );
    binding.webView.getSettings().setAppCachePath( getActivity().getApplicationContext().getCacheDir().getAbsolutePath() );
    binding.webView.getSettings().setAllowFileAccess( true );
    binding.webView.getSettings().setAppCacheEnabled( true );
    binding.webView.getSettings().setCacheMode( WebSettings.LOAD_DEFAULT );
    if ( !ConnectivityStatus.Companion.isConnected(getContext()) ) { // loading offline
        binding.webView.getSettings().setCacheMode( WebSettings.LOAD_CACHE_ELSE_NETWORK );
    }
    binding.webView.loadUrl(this.url);
Kyaw San Oo
  • 157
  • 1
  • 7
-2

If your WebView is in a Fragment, please check below:

saving:

@Override
public void onSaveInstanceState(Bundle outState) {
    webView.saveState(outState); // output would be a WebBackForwardList
}

You may check the doc for saveState.

restoring:

@Override
public void onCreate(Bundle savedInstanceState) {
    ...

    if (savedInstanceState != null) {
        webView.restoreState(savedInstanceState);
    } else {
        webView.loadUrl("http://mypage");
    }
}
chubao
  • 5,871
  • 6
  • 39
  • 64
  • 5
    Shouldn't you be calling `webView.restoreState()` instead of `webView.saveState()` in `onCreate()`? – SlashG Nov 15 '18 at 08:31