views:

3837

answers:

6

Just started working with the webview. The issue is performance following rotation. The WebView has to reload the page, which can be a bit tedious.

What's the best of of handling an orientation change without reloading the page from source each time?

A: 

@Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState);

}

@Override
protected void onRestoreInstanceState(Bundle state) {
 super.onRestoreInstanceState(state);

}

These methods can be overridden on any activity, it just basically allows you to save and restore values each time an activity is created/destroyed, when the screen orientation changes the activity gets destroyed and recreated in the background, so therefore you could use these methods to temporary store/restore states during the change.

You should have a deeper look into the two following methods and see whether it fits your solution.

http://developer.android.com/reference/android/app/Activity.html

Chiwai Chan
A: 

One compromise is to avoid rotation. Add this to fix the activity for Portrait orientation only.

android:screenOrientation="portrait"
Jacques René Mesrine
A: 

You can try using onSaveInstanceState and onRestoreInstanceState of you activity to call saveState(...) and restoreState(...) on your webview instance.

+1  A: 

I've tried using onRetainNonConfigurationInstance (returning the WebView), then getting it back with getLastNonConfigurationInstance during onCreate and re-assigning it.

Doesn't seem to work just yet. I can't help but think I'm really close though! So far, I just get a blank/white-background WebView instead. Posting here in the hopes that someone can help push this one past the finish line.

Maybe I shouldn't be passing the WebView. Perhaps an object from within the WebView?

The other method I tried - not my favorite - is to set this in the activity:

 android:configChanges="keyboardHidden|orientation"

... and then do pretty much nothing here:

@Override
public void onConfigurationChanged(Configuration newConfig) {
  super.onConfigurationChanged(newConfig);
  // We do nothing here. We're only handling this to keep orientation
  // or keyboard hiding from causing the WebView activity to restart.
}

THAT works, but it might not be considered a best practice.

Meanwhile, I also have a single ImageView that I want to automagically update depending on the rotation. This turns out to be very easy. Under my res folder, I have drawable-land and drawable-port to hold landscape/portrait variations, then I use R.drawable.myimagename for the ImageView's source and Android "does the right thing" - yay!

... except when you watch for config changes, then it doesn't. :(

So I'm at odds. Use onRetainNonConfigurationInstance and the ImageView rotation works, but WebView persistence doesn't ... or use onConfigurationChanged and the WebView stays stable, but the ImageView doesn't update. What to do?

One last note: In my case, forcing orientation isn't an acceptable compromise. We really do want to gracefully support rotation. Kinda like how the Android Browser app does! ;)

Joe D'Andrea
You shouldn't return any Views from onRetainNonConfigurationInstance. The views are attached to the Activity Context so if you save the view you carry over all that baggage every time there is an orientation change. The view is "leaked". (See last paragraph here: http://developer.android.com/resources/articles/faster-screen-orientation-change.html)The best practice for onRetainNonConfigurationInstance is to save the data that the view needs, not the view itself.
Declan Shanaghy
+4  A: 

If you do not want the WebView to reload on orientation changes simply override onConfigurationChanged in your Activity class:

@Override
public void onConfigurationChanged(Configuration newConfig){        
    super.onConfigurationChanged(newConfig);
}

And set the android:configChanges attribute in the manifest:

<activity android:name="..."
          android:label="@string/appName"
          android:configChanges="orientation"

for more info see:
http://developer.android.com/intl/de/reference/android/app/Activity.html#ConfigurationChanges

Totach
I tested but found do not work, set configChanges attribute like below will work.android:configChanges="keyboardHidden|orientation"
virsir
+3  A: 

This can be handled by overrwriting onSaveInstanceState(Bundle outState) in your activity and calling saveState from the webview:

protected void onSaveInstanceState(Bundle outState) { webView.saveState(outState); }

Then recover this in your onCreate after the webview has been re-inflated of course:

public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.blah); if (savedInstanceState != null) ((WebView)findViewById(R.id.webview)).restoreState(savedInstanceState);

KWright