The advice rotation charges again my webviews class - android

When I rotate my devices, this charge again his class. For example, if I have a google search when I change the orientation charges again to google.
I've try it with:
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
setContentView(R.layout.principal);
}
and onRestoreInstanceState and onSaveInstanceState. But my problem persist. I would appreciate if somebody can help me with a example or explication of how can to do it.
Thank's!
I've solved the problem, I needed to do the if (savedInstanceState == null) :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.principal);
webview.setWebViewClient(new WebViewClient());
if (savedInstanceState == null)
{
webview.loadUrl("http://www.apple.es");
}
}
#Override
protected void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
// Save the state of the WebView
webview.saveState(outState);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState)
{
super.onRestoreInstanceState(savedInstanceState);
// Restore the state of the WebView
webview.restoreState(savedInstanceState);
}
I hope than my problem and my solution can help to somebody!

Christian you have to see this doc on android developer web site and learn how romain guy stores his last loaded image and call them when the configuration screen changes!! the solution is to use
onRetainNonConfigurationInstance()
getLastNonConfigurationInstance()
I also refer to this tutorial always to get rid of the screen change behavour of android
hope this will help you

Add configChanges in your AndroidManifest file.
For example:
<activity android:name="YourActivityName"
android:configChanges="orientation">
</activity>
and save your current url in local variable and load it in onConfigChanges
#Override
public void onConfigurationChanged(Configuration newConfig) {
yourWebView.loadUrl(yourUrl);
}

use following piece of code
public void onConfigurationChanged(Configuration newConfig) {
yourWebView.loadUrl(yourUrl);
}
Refer this link
Activity restart on rotation Android

Related

onConfigurationChanged() is not called when Dark theme changes

Firstly, I have searched StackOverFlow for many hours before I post this question.
I tried to get onConfigurationChanged() called when user changes the theme in Setting but I've got no luck, event for other configs such as: Orientation, Screen size...
Please show me where I am doing wrong.
**Manifest file : use OnConfigChanges for handling config change event **
<activity
android:name=".Notification.OnConfigChanges"
android:configChanges="keyboardHidden|orientation|screenSize|uiMode"
android:label="#string/app_name">
</activity>
OnConfigChanges class:
public class OnConfigChanges extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_on_config_changes);
Log.d("onConfig","Yes");
Toast.makeText(this,"onConfig",Toast.LENGTH_SHORT).show();
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.d("onConfig","Yes");
Toast.makeText(this,"onConfig",Toast.LENGTH_SHORT).show();
}

Persistence of data from different layouts android

I was doing an android application, in which I have two different layouts for the same activity (one for portrait and one for landscape, it is important to say that they are totally different). Well my problem the persistence of data between them, since when changing between portrait and landscape the data is lost, to try to solve my problem I used onSaveInstanceState and change the manifest, but none of them serves in my case. I hope you can help me, regards.
pd. Landscape is in the directory layout-land
mensaje=(EditText) findViewById(R.id.EditTextAlarma); //portrait
horaEdit=(EditText) findViewById(R.id.editTextHoras); //landscape
minutosEdit=(EditText) findViewById(R.id.editTextMinutos); //landscape
segundosEdit=(EditText) findViewById(R.id.editTextSegundos); //landscape
mensajeTimer=(EditText) findViewById(R.id.mensajeTimer); //landscape
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("msj",mensaje.getText().toString());
outState.putString("hora",horaEdit.getText().toString());
outState.putString("min",minutosEdit.getText().toString());
outState.putString("seg",segundosEdit.getText().toString());
outState.putString("msjT",mensajeTimer.getText().toString());
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
String m=savedInstanceState.getString("msj");
String h=savedInstanceState.getString("hora");
String mn=savedInstanceState.getString("min");
String s=savedInstanceState.getString("seg");
String mt=savedInstanceState.getString("msjT");
mensaje.setText(m);
horaEdit.setText(h);
minutosEdit.setText(mn);
segundosEdit.setText(s);
mensajeTimer.setText(mt);
}
Override this two methods from your activity
Then when orientation changes just get the value in onRestoreInstanceState and set it to xml widget
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//SAVE YOUR DATA HERE
outState.putString("key","Value");
//YOU CAN SAVE ANY TYPE OF DATA HERE AND RETRIVE
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
//RETRIVE YOUR DATA HERE
String value=savedInstanceState.getString("key");
//SET VALUE TO XML HERE
Log.d("Value saved is:",value);
}

Orientation change with activity that download from internet. Android

Im developing an app that download tweets from twitter.
When my app change orientation, the activity loads again the tweets (it downloads again the same tweets).
So whats the best solution for a case like this ?
Is using android:configChanges="orientation|keyboardHidden|screenSize" a way to go ? I have read that is a bad practice.
Thanks
You can override onSaveInstanceState and onRestoreInstanceState to avoid downloading same tweets again.
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putSerializable(<Key>, <Value>);
super.onSaveInstanceState(savedInstanceState);
}
When the orientation is changed, restore the saved tweets.
[Edit]
Alternatively, you can do it without overriding onRestoreInstanceState:
public void onCreate(Bundle savedInstanceState) {
if (savedInstanceState!= null) {
value = savedInstanceState.getSerializable(<Key>);
}
}
More information here.

Android : How to forbird re-creation of Activity when orientation changed?

I have an Android Activity with Frgment. When my application is started, a listview is loaded with 10 elements which are sent from a server. (simple request).
When i change the orientation of my device, the activity is recreated, i see also the spinner with my request to load my listview.
How can i do to forbid re-creation of Activity ?
I already set the flag :
android:configChanges="orientation|keyboardHidden|screenSize"
And onConfigurationChanged :
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
}
You then want to override
#Override
public void onConfigurationChanged(Configuration newConfig)
{
}
in your activity, with what you want to do on orientation/keyboardHidden/screenSize.
Setting the flag in the manifest tells the app that you want to handle those configuration changes yourself.
You need to override onSaveInstanceState(Bundle savedInstanceState) and keep state of all the values that you need when orientation changes.
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
// This bundle will be passed to onCreate if the process is
// killed and restarted.
savedInstanceState.putString("jsonArrayString", jsonArrayStrin);
// etc.
}
This value will be passed to the onCreate and/or onRestoreInstanceState. You can retrieve this using following :
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// This bundle has also been passed to onCreate.
String myArrayString = savedInstanceState.getString("jsonArrayString");
}
Hope this helps
If you don't need the orientation to change, you can also prevent it in the manifest. Just specify in the activity element the attribute: android:screenOrientation

Android WebView: handling orientation changes

The issue is the performance following rotation. The WebView has to reload the page, which can be a bit tedious.
What's the best way of handling an orientation change without reloading the page from source each time?
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|screenSize"
for more info see:
http://developer.android.com/guide/topics/resources/runtime-changes.html#HandlingTheChange
https://developer.android.com/reference/android/app/Activity.html#ConfigurationChanges
Edit: This method no longer works as stated in the docs
Original answer:
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);
}
The best answer to this is following Android documentation found here
Basically this will prevent Webview from reloading:
<activity android:name=".MyActivity"
android:configChanges="keyboardHidden|orientation|screenSize|layoutDirection|uiMode"
android:label="#string/app_name">
Edit(1/4/2020): You don't need this optional code, the manifest attribute is all you need, leaving optional code here to keep answer complete.
Optionally, you can fix anomalies (if any) by overriding onConfigurationChanged in the activity:
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Checks the orientation of the screen
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
}
}
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! ;)
Best way to handle orientation changes and Preventing WebView reload on Rotate.
#Override
public void onConfigurationChanged(Configuration newConfig){
super.onConfigurationChanged(newConfig);
}
With that in mind, to prevent onCreate() from being called every time you change orientation, you would have to add android:configChanges="orientation|screenSize" to the AndroidManifest.
or just ..
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"`
I appreciate this is a little late, however this is the answer that I used when developing my solution:
AndroidManifest.xml
<activity
android:name=".WebClient"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize" <--- "screenSize" important
android:label="#string/title_activity_web_client" >
</activity>
WebClient.java
public class WebClient extends Activity {
protected FrameLayout webViewPlaceholder;
protected WebView webView;
private String WEBCLIENT_URL;
private String WEBCLIENT_TITLE;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_web_client);
initUI();
}
#SuppressLint("SetJavaScriptEnabled")
protected void initUI(){
// Retrieve UI elements
webViewPlaceholder = ((FrameLayout)findViewById(R.id.webViewPlaceholder));
// Initialize the WebView if necessary
if (webView == null)
{
// Create the webview
webView = new WebView(this);
webView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
webView.getSettings().setSupportZoom(true);
webView.getSettings().setBuiltInZoomControls(true);
webView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
webView.setScrollbarFadingEnabled(true);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setPluginState(android.webkit.WebSettings.PluginState.ON);
webView.getSettings().setLoadsImagesAutomatically(true);
// Load the URLs inside the WebView, not in the external web browser
webView.setWebViewClient(new SetWebClient());
webView.setWebChromeClient(new WebChromeClient());
// Load a page
webView.loadUrl(WEBCLIENT_URL);
}
// Attach the WebView to its placeholder
webViewPlaceholder.addView(webView);
}
private class SetWebClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.web_client, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}else if(id == android.R.id.home){
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onBackPressed() {
if (webView.canGoBack()) {
webView.goBack();
return;
}
// Otherwise defer to system default behavior.
super.onBackPressed();
}
#Override
public void onConfigurationChanged(Configuration newConfig){
if (webView != null){
// Remove the WebView from the old placeholder
webViewPlaceholder.removeView(webView);
}
super.onConfigurationChanged(newConfig);
// Load the layout resource for the new configuration
setContentView(R.layout.activity_web_client);
// Reinitialize the UI
initUI();
}
#Override
protected void onSaveInstanceState(Bundle outState){
super.onSaveInstanceState(outState);
// Save the state of the WebView
webView.saveState(outState);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState){
super.onRestoreInstanceState(savedInstanceState);
// Restore the state of the WebView
webView.restoreState(savedInstanceState);
}
}
One compromise is to avoid rotation.
Add this to fix the activity for Portrait orientation only.
android:screenOrientation="portrait"
Just write the following code lines in your Manifest file - nothing else. It really works:
<activity android:name=".YourActivity"
android:configChanges="orientation|screenSize"
android:label="#string/application_name">
You can try using onSaveInstanceState() and onRestoreInstanceState() on your Activity to call saveState(...) and restoreState(...) on your WebView instance.
It is 2015, and many people are looking for a solution that still workds on Jellybean, KK and Lollipop phones.
After much struggling I found a way to preserve the webview intact after you change orientation.
My strategy is basically to store the webview in a separate static variable in another class. Then, if rotation occurs, I dettach the webview from the activity, wait for the orientation to finish, and reattach the webview back to the activity.
For example... first put this on your MANIFEST (keyboardHidden and keyboard are optional):
<application
android:label="#string/app_name"
android:theme="#style/AppTheme"
android:name="com.myapp.abc.app">
<activity
android:name=".myRotatingActivity"
android:configChanges="keyboard|keyboardHidden|orientation">
</activity>
In a SEPARATE APPLICATION CLASS, put:
public class app extends Application {
public static WebView webview;
public static FrameLayout webviewPlaceholder;//will hold the webview
#Override
public void onCreate() {
super.onCreate();
//dont forget to put this on the manifest in order for this onCreate method to fire when the app starts: android:name="com.myapp.abc.app"
setFirstLaunch("true");
}
public static String isFirstLaunch(Context appContext, String s) {
try {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(appContext);
return prefs.getString("booting", "false");
}catch (Exception e) {
return "false";
}
}
public static void setFirstLaunch(Context aContext,String s) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(aContext);
SharedPreferences.Editor editor = prefs.edit();
editor.putString("booting", s);
editor.commit();
}
}
In the ACTIVITY put:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(app.isFirstLaunch.equals("true"))) {
app.setFirstLaunch("false");
app.webview = new WebView(thisActivity);
initWebUI("www.mypage.url");
}
}
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
restoreWebview();
}
public void restoreWebview(){
app.webviewPlaceholder = (FrameLayout)thisActivity.findViewById(R.id.webviewplaceholder);
if(app.webviewPlaceholder.getParent()!=null&&((ViewGroup)app.webview.getParent())!=null) {
((ViewGroup) app.webview.getParent()).removeView(app.webview);
}
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.FILL_PARENT);
app.webview.setLayoutParams(params);
app.webviewPlaceholder.addView(app.webview);
app.needToRestoreWebview=false;
}
protected static void initWebUI(String url){
if(app.webviewPlaceholder==null);
app.webviewPlaceholder = (FrameLayout)thisActivity.findViewById(R.id.webviewplaceholder);
app.webview.getSettings().setJavaScriptEnabled(true); app.webview.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
app.webview.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
app.webview.getSettings().setSupportZoom(false);
app.webview.getSettings().setBuiltInZoomControls(true);
app.webview.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
app.webview.setScrollbarFadingEnabled(true);
app.webview.getSettings().setLoadsImagesAutomatically(true);
app.webview.loadUrl(url);
app.webview.setWebViewClient(new WebViewClient());
if((app.webview.getParent()!=null)){//&&(app.getBooting(thisActivity).equals("true"))) {
((ViewGroup) app.webview.getParent()).removeView(app.webview);
}
app.webviewPlaceholder.addView(app.webview);
}
Finally, the simple XML:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".myRotatingActivity">
<FrameLayout
android:id="#+id/webviewplaceholder"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>
There are several things that could be improved in my solution, but I already spent to much time, for example: a shorter way to validate if the Activity has been launched for the very first time instead of using SharedPreferences storage.
This approach preserves you webview intact (afaik),its textboxes, labels, UI, javascript variables, and navigation states that are not reflected by the url.
The only thing you should do is adding this code to your manifest file:
<activity android:name=".YourActivity"
android:configChanges="orientation|screenSize"
android:label="#string/application_name">
Update: current strategy is to move WebView instance to Application class instead of retained fragment when it's detached and reattach on resume as Josh does.
To prevent Application from closing, you should use foreground service, if you want to retain state when user switches between applications.
If you are using fragments, you can use retain instance of the WebView.
The web view will be retained as instance member of the class. You should however attach web view in OnCreateView and detach before OnDestroyView to prevent it from destruction with the parent container.
class MyFragment extends Fragment{
public MyFragment(){ setRetainInstance(true); }
private WebView webView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = ....
LinearLayout ll = (LinearLayout)v.findViewById(...);
if (webView == null) {
webView = new WebView(getActivity().getApplicationContext());
}
ll.removeAllViews();
ll.addView(webView, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
return v;
}
#Override
public void onDestroyView() {
if (getRetainInstance() && webView.getParent() instanceof ViewGroup) {
((ViewGroup) webView.getParent()).removeView(webView);
}
super.onDestroyView();
}
}
P.S. Credits go to kcoppock answer
As for 'SaveState()' it no longer works according to official documentation:
Please note that this method no longer stores the display data for
this WebView. The previous behavior could potentially leak files if
restoreState(Bundle) was never called.
#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
The best solution I have found to do this without leaking the previous Activity reference and without setting the configChanges.. is to use a MutableContextWrapper.
I've implemented this here: https://github.com/slightfoot/android-web-wrapper/blob/48cb3c48c457d889fc16b4e3eba1c9e925f42cfb/WebWrapper/src/com/example/webwrapper/BrowserActivity.java
This is the only thing that worked for me (I even used the save instance state in onCreateView but it wasn't as reliable).
public class WebViewFragment extends Fragment
{
private enum WebViewStateHolder
{
INSTANCE;
private Bundle bundle;
public void saveWebViewState(WebView webView)
{
bundle = new Bundle();
webView.saveState(bundle);
}
public Bundle getBundle()
{
return bundle;
}
}
#Override
public void onPause()
{
WebViewStateHolder.INSTANCE.saveWebViewState(myWebView);
super.onPause();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
ButterKnife.inject(this, rootView);
if(WebViewStateHolder.INSTANCE.getBundle() == null)
{
StringBuilder stringBuilder = new StringBuilder();
BufferedReader br = null;
try
{
br = new BufferedReader(new InputStreamReader(getActivity().getAssets().open("start.html")));
String line = null;
while((line = br.readLine()) != null)
{
stringBuilder.append(line);
}
}
catch(IOException e)
{
Log.d(getClass().getName(), "Failed reading HTML.", e);
}
finally
{
if(br != null)
{
try
{
br.close();
}
catch(IOException e)
{
Log.d(getClass().getName(), "Kappa", e);
}
}
}
myWebView
.loadDataWithBaseURL("file:///android_asset/", stringBuilder.toString(), "text/html", "utf-8", null);
}
else
{
myWebView.restoreState(WebViewStateHolder.INSTANCE.getBundle());
}
return rootView;
}
}
I made a Singleton holder for the state of the WebView. The state is preserved as long as the process of the application exists.
EDIT: The loadDataWithBaseURL wasn't necessary, it worked just as well with just
//in onCreate() for Activity, or in onCreateView() for Fragment
if(WebViewStateHolder.INSTANCE.getBundle() == null) {
webView.loadUrl("file:///android_asset/html/merged.html");
} else {
webView.restoreState(WebViewStateHolder.INSTANCE.getBundle());
}
Although I read this doesn't necessarily work well with cookies.
try this
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class MainActivity extends AppCompatActivity {
private WebView wv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
wv = (WebView) findViewById(R.id.webView);
String url = "https://www.google.ps/";
if (savedInstanceState != null)
wv.restoreState(savedInstanceState);
else {
wv.setWebViewClient(new MyBrowser());
wv.getSettings().setLoadsImagesAutomatically(true);
wv.getSettings().setJavaScriptEnabled(true);
wv.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
wv.loadUrl(url);
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
wv.saveState(outState);
}
#Override
public void onBackPressed() {
if (wv.canGoBack())
wv.goBack();
else
super.onBackPressed();
}
private class MyBrowser extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
}
}
This page solve my problem but I have to make slight change in initial one:
protected void onSaveInstanceState(Bundle outState) {
webView.saveState(outState);
}
This portion has a slight problem for me this. On the second orientation change the application terminated with null pointer
using this it worked for me:
#Override
protected void onSaveInstanceState(Bundle outState ){
((WebView) findViewById(R.id.webview)).saveState(outState);
}
You should try this:
Create a service, inside that service, create your WebView.
Start the service from your activity and bind to it.
In the onServiceConnected method, get the WebView and call the setContentView method to render your WebView.
I tested it and it works but not with other WebViews like XWalkView or GeckoView.
#Override
protected void onSaveInstanceState(Bundle outState )
{
super.onSaveInstanceState(outState);
webView.saveState(outState);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState)
{
super.onRestoreInstanceState(savedInstanceState);
webView.restoreState(savedInstanceState);
}
I like this solution http://www.devahead.com/blog/2012/01/preserving-the-state-of-an-android-webview-on-screen-orientation-change/
According to it we reuse the same instance of WebView. It allows to save navigation history and scroll position on configuration change.

Categories

Resources