Do variables retain values on orientation change? - android

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.

Related

Locking Android orientation based on preference

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 :)

Storing complex computed data between orientation change

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.

Android AsyncTask return dismissing a ProgressDialog after screen rotation

Here's the scenario:
Account login page
Clicking on "Sign-in" triggers a login AsyncTask
To block the UI during network access, a ProgressDialog pops up
Upon returning, the ProgressDialog is dismissed and the user forwarded on
This flow works very well.
Here's the problem:
The user may rotate the screen while the AsyncTask is logging him/her in
Presently, the ProgressDialog is referenced by a class field, and dismissed using that pointer and call to .dismiss().
If the screen is rotated, though, everything crashes.
Probably because the Activity is re-created? My suspicion is that the closure around that field reference points to an object that is unreachable. What's your take?
How can I solve it reliably and elegantly? Just add if (... != null) checks?
More generally, I must confess I don't understand the "best practice" to apply in cases like this:
Activity A triggers an AsyncTask
The user navigates away from Activity A (back button? rotate screen? onClick that starts an Intent?)
The AsyncTask returns when Activity A is not the topmost one anymore yet its onPostExecute() has a UI effect , note: the original delegate observer is not available anymore.
Confused * (note: I am a beginner, so a thorough explanation would help me a lot)
Yes on changing the orientation, the activity is destroyed then recreated it again.
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. Instead, the activity remains running and its onConfigurationChanged() method is called.
Add this line android:configChanges="orientation|keyboardHidden" to your manifest file
<activity
android:name=""
android:label=""
android:configChanges="orientation|keyboardHidden" />
I recommend looking at Handling Runtime Changes. For a detailed explanation of the details of the methods available to you.
android:configChanges="orientation..." tells android your application will take care of resizing the current view hierarchy. As such, when you specify that in your manifest, your activity will not be destroyed and recreated, instead the system will just call your activity's `onConfigurationChanged()` method. As it so happens, most of the stock widgets will resize themselves when their container changes, so if you are using basic layouts, this usually "just works" by redrawing the view hierarchy in the new format. For custom widgets, this trick may not work.
The approved method is to save some configuration instance information when you are being destroyed in the onSaveInstanceState() method, and then recreate your state in onCreate()
In your case, the dialog is dismissed when then screen changes orientation, so you can either leave it that way, or reopen it in your onCreate().

android screen orientation conflict

I have a method in my main class, that fetches some data from the internet. The thing is that after everything is done, if I change the screen orientation by moving the device, everything starts allover again(fetching data while displaying a loading screen). Is there somewhere I could put my method so that if my device's screen orientation changes, it won't erase everything that has been done until that moment? Thanks.
What is happening to you is that every time you rotate your activity is recreated, as per android good practices you should handle your activity being recreated because android may destroy your activity at any point if resources go low on the device. Take a look at saving the state of your activity and how to restore it and the link.
Example using onSaveInstanceState()
You can use a singleton class to store your data.
If you prefer a simpler way you can also put your data as static, so the orientation change will not throw them away.
I think that your Activity is getting recreated again. In that case,it will load again.
1). You can handle orientation change by overriding
public void onConfigurationChanged(Configuration newConfig)
and in your activity declaration in manifest file add the following line
android:configChanges="orientation|screenSize|keyboardHidden"
2). As Aerilys said in the above answer, you can use singleton class to store data. Before displaying your loading screen check if you single ton object has data or not. If yes then skip displaying your loading screen

Forcing Android to not redraw activity on orientation change

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.

Categories

Resources