I'm haveing some problems with orientation changes. When my app changes its orientation, database is cleared. Is it something I'm doing wrong or is just its default behaivour and I have to restore and save database with onSaveInstanceState()
Thanks
open your manifest.xml file and change Activity<> tag as below: then check
<activity
android:configChanges="keyboardHidden|orientation"></activity>
If you are recreating the database in onCreate, then you will see this behaviour unless you also implement onSaveInstanceState and either onRestoreInstanceState or use the SavedInstanceState arg to onCreate to restore what you previously saved (or both).
The whole point of Save/RestoreInstanceState is for those times where the system needs to kill and recreate your activity without the user knowing, so you need to preserve the illusion that you have been running all along. The two most likely instances where this will occur are
on an orientation change
if your activity is in the background and the system is running low on memory.
Related
What is the significance of:
super.onCreate(null);
instead of
super.onCreate(savedInstanceState);
With this change, I am able to avoid many problems that otherwise plague my Activitys each time a configuration change occurs (rotation, locale shift, permission toggle). It seems that with this change, the Activity is started afresh whenever a configuration change triggers it to restart. And I don't seem to lose any data or process state by doing this: all my Activitys are restored exactly to their former state.
My question is, can I do this with impunity henceforth, or am losing something in the bargain? I don't really understand why this works, whether it is safe or not, and what unintended effects it may have on my app.
I chanced upon this trick here.
Related Questions:
Calling super.onCreate() with null parameter?
Will 'Bundle savedInstanceState' be alive after Application is being killed?
Activity state instance - insights?
Activity's instance state: what is automatically stored and restored
onCreate() call first when activity is about to create, Also Android System manage activity lifecycle and can kill the activity with saving its instanceState, in case if acitvity out of focus for user for long time and system is on low memory situation.
An activity has essentially four states
super.onCreate(null) : Would always create activity as it is creating fisrt time , even Android system provide its savedInstanceState, and does't matter what orientation configurations are.
super.onCreate(savedInstanceState) : Activity can use 'savedInstanceState' to reset its state or component where it was last.
To achive this, acitivty's instance state need to be persist before activity lost user attention( that could be onStop or onDestroy)
savedInstaceState can also be important to handle if activity configuration got changed, Please check acitvity life cycle behavior on Configuration change
am losing something in the bargain?
Only if you are working with Fragments. see Calling super.onCreate() with null parameter?
Yes, onCreate(...) is necessary to start an Activity, but passing Bundle as an argument is required when you are working with fragments.
What did you infer from that?
The argument savedInstanceState is anyway null by default. So you aren't really losing anything in a bargain.
But wait, we usually use Bundles to maintain orientation change, right?
the following manifest code declares an activity that handles both the screen orientation change and keyboard availability change:
<activity android:name=".MyActivity"
android:configChanges="orientation|keyboardHidden"
android:label="#string/app_name">
Now, when one of these configurations change, MyActivity does not restart. Instead, the MyActivity receives a call to onConfigurationChanged(). This method is passed a Configuration object that specifies the new device configuration. By reading fields in the Configuration, you can determine the new configuration and make appropriate changes by updating the resources used in your interface. At the time this method is called, your activity's Resources object is updated to return resources based on the new configuration, so you can easily reset elements of your UI without the system restarting your activity.
the following onConfigurationChanged() implementation checks the current device orientation:
#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();
}
}
But Remember: When you declare your activity to handle a configuration change, you are responsible for resetting any elements for which you provide alternatives. If you declare your activity to handle the orientation change and have images that should change between landscape and portrait, you must re-assign each resource to each element during onConfigurationChanged().
As far as I know a lot of data is saved in the bundle savedInstanceState.
E.g. all the views' states in your current layout, such as the current content of any EditText or CheckBox.
You could also look up some official sources to check whether you need to keep some data.
Here's a nice article about it
Basically it says that all View class implements the methods onRestoreInstanceState and onSaveInstanceState, which are saving and restoring any temporary states they were in before the state change.
The savedInstanceState is a reference to a Bundle object that is passed into the onCreate method of every Android Activity. Activities have the ability, under special circumstances, to restore themselves to a previous state using the data stored in this bundle.
It is very important to use savedInstantState to get values from Intent which is saved in the bundle.
All your data stored in class variables or local variables is lost whenever you change rotation of device, but in your activity it looks like you have not stored any data as long as user enters any data, but instead you are perhaps reading data on click of a button or something like that, your activity will behave and work normally, and all user inputs like text inside EditText will be restored by Android itself, because it identifies "IDs" (android:id="#+id/anyID") allotted to each view and can restore by itself all the values inserted by user.
I hope this this helps you...
Happy coding :)
I have problem with my activity
when I change the phone's orientation, the activity runs the onCreate method agaian
(and my program downloads a file in onCreate)
how can I make activity not restart after orientation change ?
This is the default behaviour for Android Activities - They get recreated whenever you change the device configuration.
To change this behaviour, add this line to the Activity declaration in your AndroidManifest.xml:
android:configChanges="orientation|keyboardHidden|screenSize"
This will tell the system that you handle orientation changes for your Activity on your own.
android:configChanges is good, if you're not changing anything, when orientation of activity will be changed.
You can also read about handling orientation change in documentation:this and this
You should properly handle you configuration changes, you can use onSaveInstanceState to store information that given file was already downloaded - ie. with path to it. In onCreate Bundle savedInstanceState will be non null after configuration change, you can read information on your downloaded file from it.
If you will use android:configChanges, then it will not solve your problem. Once you go to other app, android might destroy your activity, when you will go back to your app, android will recreate it again - and you again will start downloading your file.
In the onCreate() of my MainActivity, my app does an intensive operation to generate some data set (runs in a separate thread, but takes some 2 - 3 seconds to complete normally). Now my problem is that, when orientation changes, the app again does this complex computation again.
Since I haven't done anything like this before, I was wondering if there is a way around this. My first thought was to store the computed data in a static variable, so that the data is persisted between different instances of MainActivity. I am guessing this is not the best approach.
My data set consists of a Map and an ArrayList and not a simple data type, if it helps.
I have looked at the onSaveInstanceState(), but it only provides to store values like int, String, etc.
In addition to what #Raghunandan suggested you can read the official docs on Recreating an Activity .
It says:
Your activity will be destroyed and recreated each time the user rotates the screen. When the screen changes orientation, the system destroys and recreates the foreground activity because the screen configuration has changed and your activity might need to load alternative resources (such as the layout.
It also introduces the concept of
onSaveInstanceState()(To save additional data about the activity state, you must override this method) and
onRestoreInstanceState() method (The default implementation of this method performs a restore of any view state that had previously been frozen by onSaveInstanceState(Bundle)).
You can also see the sample implementation of these methods here Saving Android Activity state using Save Instance State thread, which will help you to save and restore the state.
Update
You may also try using:
<activity name= ".YourActivity" android:configChanges="orientation|screenSize"/>
The docs for android:configChanges say;
It lists configuration changes that the activity will handle itself. When a configuration change occurs at runtime, the activity is shut down and restarted by default, but declaring a configuration with this attribute will prevent the activity from being restarted. Source: How to save state during orientation change in Android if the state is made of my classes?
Hope this helps.
Why should I need to use setRetainInstance() or onSaveInstance() to save state and I can use android:configChanges="keyboard|orientation|screenLayout" and get the samething "saving state non-UI state"? I mean with less headache.
Don't use android:configChanges. It will break things in subtle ways and will prevent Android from getting the proper layout/theme/dimensions, etc. for the current configuration.
onSaveInstanceState() is completely orthogonal to this: you need to save state so you can restore it if Android kills your process to save memory. configChagnes only prevents it from re-creating the activity on rotation, keyboard state changes, etc.
setRetainInstance() is for fragments that you don't want re-created on device rotation, etc. If you don't call it, Android will serialize their state in a Bundle, and re-create them along with the parent activity.
In short, while configChanges appears to be a 'shortcut' it is not. Don't rely on it and save/restore state as necessary using the proper tools for each case.
I am facing problem in building android webview . The problem is that when the app is running and phone change direction , i mean from horizontal to vertical or vice versa the app get restarted. Thanks
The default behavior is to restart the activity when the screen orientation changes. You can write custom code to handle orientation change events yourself though:
Add android:configChanges="orientation" to your AndroidManifest.xml
Override onConfigurationChanged from your activity
The default android behaviour is to destroy and recreate the activity on orientation change. You can either override onSaveInstanceState() to save your application data before destroy, or you can call onRetainNonConfigurationInstance() to keep hold of a stateful object. See the android docs.
Umar,
You will want to add the android:configChanges="orientation" parameter to your Activity in your AndroidManifest.xml to prevent your activity from restarting on orientation change.
See: http://developer.android.com/guide/topics/manifest/activity-element.html#config
Another possibility (usually a decent fit for lighter Activities that don't have state outside a WebView, for instance) is to absorb the rotation event and let the view redraw itself. See http://www.androidguys.com/2008/11/11/rotational-forces-part-three/ - the idea is:
Put an android:configChanges entry in
your file, listing the configuration
changes you want to handle yourself
versus allowing Android to handle for
you.
Implement onConfigurationChanged()
in your Activity, which will be called
when one of the configuration changes
you listed in android:configChanges
occurs
See also: Activity restart on rotation Android
umar... Saving instance state is quite different on the Android. On a soft kill (phone rotation) you may save your non view state in onSaveInstanceState using bundles. On a hard kill (back button while activity has focus) you may elect to save your non view and view state in onStop perhaps using preferences. You can restore your state in onCreate.
You can leverage the fact that IF onSaveInstanceState is called it will be called BEFORE onStop. So this lets you set a flag isSavedInstanceState to true in onSaveInstanceState to avoid saving prefs in onStop except on a hard kill. The trick is to reset the flag isSavedInstanceState to false in onResume NOT in onCreate.
JAL
I have sample code here.