I have an app that adds to a total variable when a button is clicked.
However if I turn my phone so the layout gets turned into the horizontal layout the values all get reset, and idea why this is and how to stop it?
Thanks!
When you move your device, your device's Orientation State changes from Portrait to Landscape of from Lanscape to Portrait.
In this Orientation change, your Activity's onCreate Method is called every time.
Therefore the values in your Activity are being reset.
There are 2 ways of solving this problem:
1) Let You Activity manage it for you.
2) Managing the changes yourself by saving and restoring states.
Using 1st way of solving this problem:
Just add this line in your Activity Node in your Manifest.xml file.
android:configChanges="orientation|keyboardHidden|screenSize"
For example:
<activity
android:name=".MyMainActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="#string/app_name" >
Using the second Way:
You can override these two Methods:
public void onSaveInstanceState(Bundle bundle) {
super.onSaveInstanceState(bundle);
//Manage your Data Explicitly here.
}
public void onRestoreInstanceState(Bundle bundle) {
super.onRestoreInstanceState(bundle);
//Manage your Data Explicitly here.
}
EDITAccording to Android Dev Guide:
Using android:configChanges="orientation|keyboardHidden|screenSize" is not a good practice.
Quote from this page
Note: Using this attribute should be avoided and used only as a last resort. Please read Handling Runtime Changes for more information about how to properly handle a restart due to a configuration change.
I recommend you to follow the Android Dev Guide for Handling Run-time Changes and follow the good Practices.
you need to save the variable in OnSaveInstanceState and restore it in onRestoreInstnace state
For example;
#Override
public void onSaveInstanceState(Bundle bundle) {
bundle.putParcelableArrayList(PEOPLE, people);
super.onSaveInstanceState(bundle);
}
#Override
public void onRestoreInstanceState(Bundle bundle) {
super.onRestoreInstanceState(bundle);
people = bundle.getParcelableArrayList(PEOPLE);
}
This happens because the normal way Android handles an activity during any configuration change (including screen reorientations) is to destroy the activity and recreate it. As described in the guide topic Handling Runtime Changes, you can handle it a couple of ways. The "Android way" is to save your activity's state information by overriding onSaveInstanceState and onRestoreInstanceState methods. The details about how to use these methods can be found in the guide topic Recreating an Activity.
The other way to prevent this problem is to tell Android that your activity will handle configuration changes internally. You do this by adding android:configChanges="orientation" to the <activity> tag in the manifest for the activity and overriding the onConfigurationChanged method of the activity to actually handle the changes.
I'm looking for a single answer (but I might be asking the wrong question)
Question- does any event only get called once TOTAL until an activity is destroyed?
I ask because when my user rotates the phone to landscape oncreate and onstart are both invoked causing a reload of sorts.
I'm looking for an event that I could put behavior into that would only get run 1x (until the activity is killed)
Thank you in advance
If it is specific to the Activity just check your savedInstanceState parameter in the onCreate event. If it is null, run your code, if not, your code has already been run.
Example:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
if(savedInstanceState == null) {
// Run your code
}
}
savedInstanceState will always be null when onCreate is run for the first time, and it will be populated thereafter.
You don't really specify what you're trying to do with it, so I can't guarantee this is appropriate for your use, but Application.onCreate is only called once.
If you want to eliminate the recreation of your activity on an orientationchange you can listen for configchanges in the manifest.
<activity
android:name=".MyActivity"
android:configChanges="orientation" >
</activity>
And then you can override onConfigurationChanged like so:
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged( newConfig );
LinearLayout main = (LinearLayout) findViewById( R.id.mainLayout );
main.requestLayout();
}
to recreate the layout so that it matches the new orientation, without recreating the entire activity.
Check http://developer.android.com/guide/topics/resources/runtime-changes.html to handle configuration changes and to maintain your huge data between them...if all you need to maintain between the configuration change is just the settings,you can use the onSavedInstanceState() and onRestoreInstanceState() callbacks and the given bundles.
I'm interested to know which methods are overridden, when an Android device is rotated (i.e. when configuration changes)?
onSaveInstanceState(...), onConfigurationChanged(...), onRestoreInstanceState(...) - something similar to this?
It will be also interesting for me to listen about the whole process connected with changing a configuration. Thanks.
According to the android developer reference you have to use:
#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();
}
}
For more information see: http://developer.android.com/guide/topics/resources/runtime-changes.html#HandlingTheChange
You could be interested in seeing: http://developer.android.com/guide/topics/manifest/activity-element.html#config
Here you can find all configuration listener you can listen.
Remember to put them in the android manifest:
<activity
android:configChanges=["orientation"]
. . .
</activity>
Hope this helps...
When you rotate the device your Activity will re-create and all the variables will be re-initialized. So, in that case if you want to some values to remain same on Rotation also you can store their state using the onSaveInstanceState() and you can restore in onCreate() again by checking Bundle is not null.
if(savedInstanceState != null){
// get the restore value from the Bundle
}
Where as onConfigurationChanged() will be called when you rotate the Device(Note that this will only be called if you have selected configurations you would like to handle with the configChanges attribute in your manifest). From the parameter you will get the new device configuration.
If you don't want your Activity to get re-created on rotation of Device then you have to add this line to your activity tag in the AndroidManifest file.
android:ConfigChanges="keyboardHidden|orientation"
From android developers...
To retain an Object during a runtime configuration change:
Override the onRetainNonConfigurationInstance() method to return the Object you would like to retain.
When your Activity is created again, call getLastNonConfigurationInstance() to recover your Object.
Android calls onRetainNonConfigurationInstance() between onStop() and onDestroy() when it shuts down your Activity due to a configuration change. In your implementation of onRetainNonConfigurationInstance(), you can return any Object that you need in order to efficiently restore your state after the configuration change.
A scenario in which this can be valuable is if your application loads a lot of data from the web. If the user changes the orientation of the device and the Activity restarts, your application must re-fetch the data, which could be slow. What you can do instead is implement onRetainNonConfigurationInstance() to return an object carrying your data and then retrieve the data when your Activity starts again with getLastNonConfigurationInstance().
Look at here for more info Retaining an Object During a Configuration Change you can also find example over their..
Thanks..
Go to Manifest and add:
android:configChanges="orientation|screenSize"
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"
android:configChanges="orientation|screenSize"
/>
In Main Activity: Copy and Paste this code:
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
All Done -
I would like to know if it is possible to ask Android not to reload one Activity when orientation changes (I want to reload others but to kill this one !!).
I have checked the activity properties that I can set in the manifest but no one seems to allow that.
Thanks !
Try this:
public boolean onRetainNonConfigurationInstance() {
return true;
}
public onCreate() {
if(getLastNonConfigurationInstance() != null) {
finish();
}
}
It is simple, in your activity override onConfigurationChanged(Configuration config) and kill the activity inside of that.
Ex:
#Override
public void onConfigurationChanged (Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
finish();
}
This will cause the activity to be killed when a configuration change takes place. In the manifest under config changes select orientation for your activity. You can check which type of orientation it is changing to by looking at newConfig.orientation and compare it to the constants for portrait and landscape in the Configuration class.
I would like to know if it is possible to ask Android not to reload one Activity when orientation changes (I want to reload others but to kill this one !!).
Possible? Sure. A good idea? No. Users will get very confused if a simple twist of their wrist causes the current activity to go away. They might think that your app is broken.
Ideally, you allow users to use your activities in any orientation they desire. It is their device, not yours.
If, for some reason, some activity only makes sense in one orientation (e.g., landscape), use the android:orientation attribute in the <activity> element in the manifest to keep it in that orientation.
I simply need nothing to change when the screen is rotated. My app displays a random image when it first loads and rotating the device should not select another random image.
How can I (simply) make this behavior stop?
There are generally three ways to do this:
As some of the answers suggested, you could distinguish the cases of your activity being created for the first time and being restored from savedInstanceState. This is done by overriding onSaveInstanceState and checking the parameter of onCreate.
You could lock the activity in one orientation by adding android:screenOrientation="portrait" (or "landscape") to <activity> in your manifest.
You could tell the system that you meant to handle screen changes for yourself by specifying android:configChanges="orientation|screenSize" in the <activity> tag. This way the activity will not be recreated, but will receive a callback instead (which you can ignore as it's not useful for you).
Personally I'd go with (3). Of course if locking the app to one of the orientations is fine with you, you can also go with (2).
Xion's answer was close, but #3 (android:configChanes="orientation") won't work unless the application has an API level of 12 or lower.
In API level 13 or above, the screen size changes when the orientation changes, so this still causes the activity to be destroyed and started when orientation changes.
Simply add the "screenSize" attribute like I did below:
<activity
android:name=".YourActivityName"
android:configChanges="orientation|screenSize">
</activity>
Now, when you change orientation (and screen size changes), the activity keeps its state and onConfigurationChanged() is called. This will keep whatever is on the screen (ie: webpage in a Webview) when the orientation changes.
Learned this from this site:
http://developer.android.com/guide/topics/manifest/activity-element.html
Also, this is apparently a bad practice so read the link below about Handling Runtime Changes:
http://developer.android.com/guide/topics/resources/runtime-changes.html
You just have to go to the AndroidManifest.xml and inside or in your activities labels, you have to type this line of code as someone up there said:
android:configChanges="orientation|screenSize"
So, you'll have something like this:
<activity android:name="ActivityMenu"
android:configChanges="orientation|screenSize">
</activity>
Hope it works!
<activity android:name="com.example.abc"
android:configChanges="orientation|screenSize"></activity>
Just add android:configChanges="orientation|screenSize" in activity tab of manifest file.
So, Activity won't restart when orientation change.
It's my experience that it's actually better to just deal with the orientation changes properly instead of trying to shoehorn a non-default behavior.
You should save the image that's currently being displayed in onSaveInstanceState() and restore it properly when your application runs through onCreate() again.
This solution is by far the best working one. In your manifest file add
<activity
android:configChanges="keyboardHidden|orientation|screenSize"
android:name="your activity name"
android:label="#string/app_name"
android:screenOrientation="landscape">
</activity
And in your activity class add the following code
#Override
public void onConfigurationChanged(Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
//your code
} else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
//your code
}
}
In manifiest file add to each activity this. This will help
android:configChanges = "orientation|keyboard|keyboardHidden|screenLayout|screenSize"
add android:configChanges="keyboardHidden|orientation|screenSize" for all the app activities tags in manifest.
Just add this to your AndroidManifest.xml
<activity android:screenOrientation="landscape">
I mean, there is an activity tag, add this as another parameter. In case if you need portrait orientation, change landscape to portrait. Hope this helps.
just use : android:configChanges="keyboardHidden|orientation"
As Pacerier mentioned,
android:configChanges="orientation|screenSize"
All above answers are not working for me. So, i have fixed by mentioning the label with screenOrientation like below. Now everything fine
<activity android:name=".activity.VideoWebViewActivity"
android:label="#string/app_name"
android:configChanges="orientation|screenSize"/>
http://animeshrivastava.blogspot.in/2017/08/activity-lifecycle-oncreate-beating_3.html
#Override
protected void onSaveInstanceState(Bundle b)
{
super.onSaveInstanceState(b);
String str="Screen Change="+String.valueOf(screenChange)+"....";
Toast.makeText(ctx,str+"You are changing orientation...",Toast.LENGTH_SHORT).show();
screenChange=true;
}
Prevent Activity to recreated
Most common solution to dealing with orientation changes by setting the android:configChanges flag on your Activity in AndroidManifest.xml. Using this attribute your Activities won’t be recreated and all your views and data will still be there after orientation change.
<activity
android:name="com.example.test.activity.MainActivity"
android:configChanges="orientation|screenSize|keyboardHidden"/>
this is work for me😊😊😊
Save the image details in your onPause() or onStop() and use it in the onCreate(Bundle savedInstanceState) to restore the image.
EDIT:
More info on the actual process is detailed here http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle as it is different in Honeycomb than previous Android versions.
I dont know if the a best solution, but i describe it here:
First of all, you need certificate with you class Application of your app is in your manifest of this:
<application
android:name=".App"
...
Second, in my class App i did like this:
public class App extends Application {
public static boolean isOrientationChanged = false;
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onConfigurationChanged(#NotNull Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE ||
newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
isOrientationChanged = true;
}
}
}
Third, you need to set a flag to Orientation Change, in my case, I always set it when the previous activity within the app navigation is called, so only calling once when the later activity is created.
isOrientationChanged = false;
So every time I change the orientation of my screen in that context, I set it every time it changes this setting, it checks if there is a change in orientation, if so, it validates it based on the value of that flag.
Basically, I had to use it whenever I made an asynchronous retrofit request, which he called every moment that changed orientation, constantly crashing the application:
if (!isOrientationChanged) {
presenter.retrieveAddress(this, idClient, TYPE_ADDRESS);
}
I don't know if it's the most elegant and beautiful solution, but at least here it's functional :)
Add this code after the onCreate ,method in your activity containing the WebView
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
#Override
protected void onRestoreInstanceState(Bundle state) {
super.onRestoreInstanceState(state);
}