Android Screen goes blank on orientation change; onConfigurationChanged is called - android

When my activity's (tab activity with two tabs) orientation is changed, the content of the tabs, which is another activity with a listview of items(with checkboxes), GOES BLANK. I have used android:configChanges="screenSize|orientation" in the manifest file, so that I dont want the checkboxes to be cleared(or recreated) on orientation change.
Could anyone please help me with this issue?

In order to save the state of View's within activities in Android you need to implement the onSaveInstanceState(Bundle outState) and onRestoreInstanceState(Bundle savedInstanceState) methods. See the Android Developer Guide for more on these methods.
onSaveInstanceState(Bundle outState) is called when the activity is destroyed on configuration change (change in orientation). You can add data to the bundle in this method and then retrieve it when the activity is restarted using onRestoreInstanceState(Bundle savedInstanceState).
For example:
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// Read values from the "savedInstanceState" bundle and put them back into the corresponding textviews
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// Save the values you need from your textviews into the outState object
}
For more details on how to save data into bundles see the Android Developer Guide. This also explains the difference between restoring state using onCreate(Bundle savedInstanceState) and onRestoreInstanceState(Bundle savedInstanceState).

Related

When is an activity forcefully recreated?

The Android docs say that configuration changes can force an activity to be recreated, the most common change being a rotation. Now, there are some methods that can determine whether an activity is being destroyed to be recreated but all(?) of these methods are called after onStop() and aren't guaranteed or recommended for data saving purposes.
To give an example, there is an EditText activity which autosaves what they have written/updated if the user navigates away from the app via back button, app switch, e.t.c. However, the user might not want to save their changes when there is a configuration change so I need to be prepared for those cases.
When an activity is destroyed by the system because of configuration change onSaveInstanceState is called.
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
Store data that you want to persist in outState bundle.
Then you'll receive the stored data in onCreate and onRestoreInstanceState.
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
}
Use it to retrieve data you had stored in onSaveInstanceState earlier.
By default System saves the state of few widgets (EditText , TextView) on it's own and this magic happens in super.onSaveInstanceState().
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
So if you do not want to save the text in EditText , just do editText.setText("") before calling super.onSaveInstanceState().
Hope this helps.

How do I save state of activities instead of always having onCreate called in Android?

I would like my application to save state after it already has loaded once. For example in one of my activities I have a ListView. If the user scrolls it, and than switches activities, I wish for them to go back to the ListView activity and have the same scrolling position. I noticed that pressing the back button goes back to a saved version of the state. This is the exact kind of save I want (where it saves the state of the previous activity). Except I want to do this from anywhere in the application, not just when the back button is pressed... Please help me.
You have to override onSaveInstanceState(Bundle savedInstanceState) and store the values you want to save in Bundle object as name value pair.
#Override public void onSaveInstanceState(Bundle savedInstanceState)
{
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putBoolean("position", 12);
savedInstanceState.putString("Name", "John");
}
also you have to override onRestoreInstanceState() where you'd extract the values:
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
boolean myPosition=savedInstanceState.getBoolean("position");
String name= savedInstanceState.getString("Name");
}
see this link for help LINK
It can be done with the saveInstanceState() and onRestoreInstanceState() methods. The first one called near onPause(), the second called before onResume(). To save the state of a view, call onSaveInstanceState() from view.
For example, listview.onSaveInstnceState();
Here's a detailed article
https://futurestud.io/blog/how-to-save-and-restore-the-scroll-position-and-state-of-a-android-listview

onCreate called whenever I the screen autorotates

In my app, I use the onCreate() method to initialize various variables. However, whenever I rotate the device, and the screen auto-rotates, onCreate() is called again, which re-initialize my variables. Is that how it's supposed to work? Where should I put code that I only want to be run once, when I start the app?
The above answers will lock your Activity into a specific orientation, which is generally not proper behavior for an Android app.
What you should be doing is storing your activity's state so when it gets recreated you can repopulate the UI with the stored values.
protected void onSaveInstanceState (Bundle outState) {
super.onSaveInstanceState(outState);
// put your values in the Bundle
outState.putString("TextView1Text", textView1.getText()); // for example;
}
Then in your onCreate() method you can restore the values
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
textView.setText(savedInstanceState.getString("TextView1Text"));
}
}
This will also work when the user leaves the app via the home button or other means.
In the manifest put this line in all the activities that you want PORTRAIT
android:screenOrientation="portrait"

Android webView saveState

I have a tabhost with 3 tabs. In each of these tabs there is a webiview.
When i click a tab the webview need to "reload" even when i have been there before, it have not been saved.
Is there any way to save the webview ?
This can be handled by overrwriting onSaveInstanceState(Bundle outState) in your activity and calling saveState from the webview:
#Override
protected void onSaveInstanceState(Bundle outState) {
webView.saveState(outState);
super.onSaveInstanceState(outState);
}
Then recover this in your onCreate after the webview has been re-inflated of course:
#Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.blah);
WebView webview = (WebView)findViewById(R.id.webview);
if (savedInstanceState != null)
webview.restoreState(savedInstanceState);
else
webview.loadUrl(URLData)
}
restoreState was never reliable. And come 2015 the documents accept the fact. (The change was probably made to the documents around 2014).
This is what it says now.
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
Alternatively you can look into using fragments with your tabHost. when entering another webView you can set fragment to hide and the other to show. when you return to the previous fragment the content will not have been destroyed. Thats how i did it and it worked for me.

Android muliple WebView save instance

I try to save and restore the state of 3 WebViews in my activity by using onSaveInstanceState() and the restoreState() method of my WebView in onCreate(). This works just fine when I had only one WebView, but with 3 WebViews to save, it looks like it's only the last one save which counts and overrides the other saves; and so when I use the restoreState() method in onCreate(), the first WebView has the content of the third WebView and the 2 others are empty.
Here is a sample of my activity code:
#Override
public void onSaveInstanceState(Bundle outState) {
((WebView)findViewById(R.id.webview1)).saveState(outState);
((WebView)findViewById(R.id.webview2)).saveState(outState);
((WebView)findViewById(R.id.webview3)).saveState(outState);
}
#Override
public void onCreate(Bundle savedInstanceState) {
((WebView)findViewById(R.id.webview1)).restoreState(savedInstanceState);
((WebView)findViewById(R.id.webview2)).restoreState(savedInstanceState);
((WebView)findViewById(R.id.webview3)).restoreState(savedInstanceState);
}
Should I use some trick to use another bundle for each view? Have I done something wrong somewhere else in my code that causes this or is it the standard behaviour?
Your 2nd call of saveState() overwrites the contents saved in the first call and the 3rd call overwrites the content of the 2nd call. At the end of the execution of onSaveInstanceState() the bundle only contains the 3rd WebView's state.
This is why when you restore the state of the 3rd WebView gets restored to the 1st WebView.
Create a new bundle object of each of your WebViews and put them into the outState Bundle object using this giving a different key for each Bundle:
public void putBundle (String key, Bundle value)
In onCreate() get the Bundles based on the 3 keys and restore the states.

Categories

Resources