I have been going gaga to figure this out.
Although I have read a lot that on Orientation Change, Android kills an activity and starts it as a fresh one, and the only way to handle this is to save all the stuff inside onSaveInstanceState() and try to restore it inside onCreate().
But my activity does a lot and different kind of network activities at different times and if the orientation is changed when the network activity is being performed, I'll have to handle a lot of different and complex scenarios.
Is there any simple way to just point Android that this activity doesn't need to be redrawn at all when the orientation is changed so that it automatically saves all the data and re-uses it?
I wonder if there's any thing like that.
Yes, you can add attribute android:configChanges="orientation" to the activity declaration in the AndroidManifest.xml file.
EDIT:
The purpose of the android:configChanges attribute is to prevent an activity from being recreated when it's really necessary. For example the Camera application uses this attribute because it the camera preview screen mustn't be recreated when an orientation change happens. Users expect the camera preview to work without any delays when they rotate their devices and camera initialization is not a very fast process. So it's kind of a native behavior for the Camera application to handle orientation changes manually.
For most applications it doesn't really matter if an activity is recreated or not during orientation changes. But sometimes it's more convenient to persist an activity during this process because of slow activity creation, asynchronous tasks performed by an activity or some other reasons. In this case it's possible to tweak an application a little and to use the android:configChanges="orientation" attribute. But what is really important to understand when you use this tweak is that you MUST implement methods for saving and restoring a state properly!
So to sum up this answer, the android:configChanges can allow you to improve the performance of an application or to make it behave "natively" in some rare cases but it doesn't reduce the amount of code you have to write.
But my activity does a lot and different kind of network activities at different times and if the orientation is changed when the network activity is being performed, I'll have to handle a lot of different and complex scenarios.
Then move that logic out of the activity and into a service.
Yes, you can add attribute
android:configChanges="orientation" to
the activity declaration in the
AndroidManifest.xml file.
IMHO, it's better to declare
android:configChanges="orientation|keyboard|keyboardHidden"
About the blog post you gave the link in another answers. I guess here is the answer:
If your application doesn't need to
update resources during a specific
configuration change and you have a
performance limitation that requires
you to avoid the Activity restart,
then you can declare that your
Activity handles the configuration
change itself, which prevents the
system from restarting your Activity.
I spoke as well with an android developer about this problem. And he meant following. If you don't have different layouts for landscape and portrait orientation, you can easy use configChanges.
I solved my problem by adding this to my activity in my manifest file
android:configChanges="keyboardHidden|orientation|screenSize"
Just answered this question earlier: Android - screen orientation reloads activity
In your case you want to completely prevent Android from killing your Activity. You'll need to update your manifest to catch the orientation change, then implement the orientation change callback to actually do whatever you need to do (which may be nothing) when an orientation change occurs.
if you are doing a lot of networking inside Asynchronous task maybe you should use onRetainNonConfigurationInstance()
ans then get the data back in your onCreate() method like this tutorial or this
add android:configChanges="orientation" to your activity in manifest and add this code in your activity class and check..i hope it will help for you.
#Override
public void onConfigurationChanged(Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
setContentView(R.layout.main);
}
this method will be called when orientation is changed nothing else if u don't want to change anything let it be blank
android:screenOrientation="portrait" in the activity tag in the manifest will lock your orientation.
Check this link for more inforation.
Related
No, not a regurgitation of the old question, please, bear with me. I don't want to avoid activity recreation in general (no android:configChanges in manifest), I don't want to fix my orientation permanently (no android:screenOrientation in manifest) just because I'm lazy to implement instance saving.
I have an app with three possible settings the user can make: 1. automatically changing layout on orientation, as per normal, 2. fixed portrait, 3. fixed landscape. It makes sense in my case because the portrait and landscape displays show different functionality and the user might want to restrict to just one. Doesn't have to but has the possibility.
The app works just fine. I read the preference setting in onCreate and call setRequestedOrientation if I'm in one of the fixed modes. I let the system handle the orientation changes, I don't ask for handling the changes myself.
The only performance problem is that when, for instance, the app is started in the device's portrait position but fixed to landscape, onCreate will be called twice, once for the original startup, once for setRequestedOrientation. It works flawlessly, I handle it perfectly but there is a performance penalty, the activity appears with an obvious delay. (With screenOrientation fixed in the manifest, only for the purpose of testing, the startup looks much better, with only a single call to onCreate).
So, what I'm looking for is a kind of code equivalent of the manifest screenOrientation setting. I can't and don't want to specify it in the manifest but calling it from onCreate is already a bit late for performance.
Try to read users preference in Application Class, and in the onCreate setContentView on the basis of that value.
public class MyApp extends Application{
public void onCreate(){
// get user preference here in a global variable
}
}
Set this as application class in Manifest.
Then in your activities onCreate, use this value to determine layout before setContentView().
did you try this?
<activity
android:name=".YourActivity"
android:configChanges="orientation|keyboard|keyboardHidden|screenSize|screenLayout|uiMode" />
This configChanges line on the manifest file should avoid the re-calling to the onCreate method :)
in my application (minSdkVersion 17, but I am flexible concerning this), I have a single activity. It displays some kind of timetable. I want to let it show the current day and scroll to the correct time.
This functionality is already working perfectly fine.
I want to do this everytime when the app is started, or everytime when the app becomes active again (e.g. after pressing the home button and just clicking the app icon again without killing the app inbetween).
But I do NOT want to do this, when the device is rotated.
For example, I have a method:
private void scrollToNow() {
// do the calculation and scroll all views to the correct position
// this is code I already have fully functional!
}
And I want to execute it every time the activity gets active again, but NOT on orientation change.
I tried a lot of combinations (in onStart, onResume, onCreate), but none of them did the trick. I tried to build a solution using the savedInstanceState but failed.
Anybody got some tips or useful links for me?
Thanks alot,
Oliver
Please, think twice before you decide to check configuration changes manually.
If your application doesn't need to update resources during a specific configuration change and you have a performance limitation that requires you to avoid the activity restart, then you can declare that your activity handles the configuration change itself, which prevents the system from restarting your activity.
Note: Handling the configuration change yourself can make it much more difficult to use alternative resources, because the system does not automatically apply them for you. This technique should be considered a last resort when you must avoid restarts due to a configuration change and is not recommended for most applications.
Try to save some flag in onSaveInstanceState and in onCreate check if there is savedInstanceState, then save it as field for example. This will give you information about does activity is 'recreated' or not. Then in 'onResume' check is this flag set or not. If not, then you are not 'recreated' your activity, so you can invoke scrollToNow()
I dont want to recreate layout when screen orientation change
Did you tried to add this line to your AndroidManifest.xml android:configChanges="screenLayout|screenSize|orientation" like that :
<activity
android:name="youractivity"
android:configChanges="screenLayout|screenSize|orientation"
android:label="#string/title_activity_create_note"
android:theme="#style/AppTheme"
android:windowSoftInputMode="stateAlwaysHidden" />
For more information you can take a look at : manifest/activity-element in that page go to android:configChanges section and read please .
When adding this you must handle onConfigurationChanged() method by yourself instead of Android System.
Please read carefully Note section in that 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.
Also i am using this in my application maybe you can try this too : android:screenOrientation="nosensor" in that page you can find information about it too.
I know that when you change the device from landscape to portrait and vice versa, the onCreate method is called. That has been a cause of some problems for me.
Say I have a database which holds the downloads that are to be performed. I plan on making a splash screen where a DAO object will convert this data into objects and put them into a Vector<DownloadTask>. This will happen on an AsyncTask's doInBackground().
onPostExecute the splash screen will start a new Activity.
All is fine so far except when I have to handle orientation change.
The new Acitivity after the splash screen will start a Timer which is responsible for scheduling the downloads. This will be started in onCreate. The DownloadTask all implement Runnable so they are threads.
When the download is over or abruptly stopped, the thread is supposed to tell this to the scheduler and decrease the number of threads running simultaneously. This is to cap the number of simultaneous downloads.
So, if the timing is right (or wrong) such that the orientation change and the fninishing of the thread line up together, what will happen to the Timer ? Will it be null ?
When orientation changes, are the variables reset to their default value ?
Also, how do I prevent orientation change ?? Like some games do
When orientation changes, are the variables reset to their default value ?
If they are Activity level variables then yes they will return to their default values since the Activity is destroyed and recreated each time. To avoid this you could either save the variables in finish() each time but this could be messy since you don't know when this might happen (but there are ways around that). You could also specify in your manifest.xml that you will handle these changes by adding
android:configChanges="orientation"
to your <activity> tags in the manifest. In the docs, they don't recommend this but I think mostly to cover their butts. I do it and haven't had any problems so far. This will keep the Activity from being destroyed.
Also, how do I prevent orientation change ??
You can do this also in the manifest by adding something like
android:screenOrientation="portrait"
to the <activity> tag for those Activities that you wish to have a certain orientation.
I have been trying to keep the loaded page and javascript values of a WebView on orientation change and pausing the activity.
First I tried overriding configChanges, but that resulted in my GUI not being updated properly (i have a slidingdrawer that changes position on orientation change). After that i tried to put the WebView in a fragment and calling setRetainInstance(true); But this does not keep the content of the WebView intact. I tried keeping the same object alive by not recreating it, but android does not allow views to be re-used in that fashion.
my question is: is there any way to keep the contents of the webview without having to reload it on every orientation change, whilst having the other GUI components update properly.
I hope my question is clear enough, but i'd be happy to elaborate if there are any unclearities.
EDIT: i already tried adding android:configChanges="keyboardHidden|orientation" in my manifest, that is what i meant by "overriding configchanges"
It seems like the only solution is to update all javascript variables again on orientation change. As I have not yet ran huge chunks of updates through javascript, I cannot provide much insight regarding the speed and resources of this operation.
I know you already tried
android:configChanges="keyboardHidden|orientation"
but try this instead
android:configChanges="keyboardHidden|orientation|screenSize"
In Android 3.2 and up "screen size" changes when you rotate which causes the webview to recreate itself. see the linked answer below for more info.
I found this answer here
https://stackoverflow.com/a/11903546/655822
Add this in your androidmanifest file..... activity
android:name=".YourActivityHere"
android:configChanges="keyboardHidden|orientation"
Try this put this in manifest
android:configChanges="orientation|keyboardHidden"></activity>
this in your class
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
Add below line in android Manifest file.
android:configChanges="keyboardHidden|orientation"
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.