Android: Retain instance of WebView content on rotation

5 comments

Unlike fragments, the WebView doesn't retain it's own instance very easily. Nothing more annoying than a web page reloading itself when you rotate the screen...

The way I managed this before in CodePeeker was to save the whole HTML string into memory and set it whenever the screen was rotated. This was slow, horribly inefficient with memory and just plain embarassing.

There have been numerous attempts at fixing it on StackOverflow, but the solution found by Andrea Bresolin seems to be the magic bullet that fixes it. His trick with keeping the WebView out of the layout XML was the missing voodoo ingredient I needed for the fix.

I managed to simplify his solution down a little further and update it for the newer API levels.

First of all, you'll need to extract your WebView out from the layout XML and move it into the code. For this to work, this control has to be created dynamically.

public class CodePeekerActivity extends Activity {
private WebView m_webview = null;
// ...
}

Secondly, ensure that your app manages the configuration changes upon rotation. In AndroidManifest.xml, add configChanges to your Activity declaration.

<activity
android:name=".CodePeekerActivity"
...
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
>

Override Activity.onSaveInstanceState().

// Save the state of the web view when the screen is rotated.
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
m_webview.saveState(outState);
}

Lastly, take control of your Activity's onCreate().

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

// Load layout
// ...

// Create WebView
m_webview = new WebView(this);

// Add WebView to Activity
// ...

// Reload the old WebView content
if (savedInstanceState != null) {
m_webview.restoreState(savedInstanceState);
}
// Create the WebView
else {
m_webview.getSettings().setJavaScriptEnabled(true);
m_webview.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
m_webview.getSettings().setBuiltInZoomControls(true);
// ... and any other configuration here
}

// ...
}

Just be sure that you're only restoring when the savedInstanceState data exists.

If you set any options before calling WebView.restoreState(), then the call to restore won't work!

Once that's all in place, you can rotate until your heart's content!

6K6YS 
Rotate I say! ROTAAAAAAAAAAATE!

Sources

Related Posts

5 comments:

  1. Man, I have been looking for this from a long time. Thank you

    ReplyDelete
    Replies
    1. You're welcome!

      If anything, I suggest putting the WebView into a Fragment so you don't have to write any of thise code at all.

      Delete
  2. Hi Twig,

    I am loading the webview into the fragment. How to save the state of the webview when I changing the orientation ?

    ReplyDelete
  3. When view is restoring page thanks saved state, then javascripts are bugged.

    I don't know why....

    ReplyDelete

Leave your thoughts ...
---
If you are having trouble with copy/pasting in comments, you need to sign in or click 'Preview'. For more information about this Firefox bug, see here.

 
Copyright © Twig's Tech Tips
Theme by BloggerThemes & TopWPThemes Sponsored by iBlogtoBlog