I am having some problems with an activity of my Android aplication.
I have discovered that my app enters twice in 'onCreateView()' method of this activity when orientation changes, and it is causing me problems. When I click the corresponding button and this activity starts is all ok, but whithin this activity when the orientation changes I have some problems because enters twice, i.e. activity restarts twice ...
... Does anyone know the behaviour of an activity when orientation changes? Why does this happen?
Thanks so much.
Since onCreateView() is not part of the Activity lifecycle, but rather is part of the Fragment, I would assume you have a fragment somewhere in your activity.
Also I would assume you add this fragment manually using FragmentManager and FragmentTransaction. Since Android keeps all the added fragments between orientation changes, it is quite possible that you don't check if your Fragment is already present in this activity, so you add it again which causes additional onCreateView to be called.
If this is the case - you need to check if your savedInstance is null within onCreate. If it is - you add fragment. Otherwise activity is getting restored, so fragment is already there.
A lot of assumptions for the answer, I know. But I'm still mastering my telepathy skills :)
When orientation changes onDestroy() is called, followed by onCreate().
For more : http://developer.android.com/guide/topics/resources/runtime-changes.html
Try to add this in AndroidMainfest.xml in your activity:
android:configChanges="orientation|screenSize|keyboardHidden"
This means not to recreate the activity when orientation changes.
Related
I would like to ask if the following behaviour is possible and, if it is, how I can achieve it. I need this behaviour for a very specific reason.
I have two activities, I will call them Activity A and Activity B. Now let's look at this example:
From activity A, in portrait orientation, I launch activity B (which has a fixed landscape orientation). The user, as the activity B is displayed in landscape, obviously rotates the device. The activity B is finished and activity A is resumed. The user keeps the device in landscape orientation so the orientation of the activity A will immediately be changed just after is resumed.
What I want is avoid that the orientation of the activity A changes when the user goes back to it. I want to resume the activity A in the last orientation it had and only allow orientation changes after that.
Locking the orientation is not an option as I want to allow the user to change it anytime.
The android:configChanges="orientation|screenSize" solution is neither an option as I want my activity to be re-created after an orientation change.
Do I have an option to achieve what I want?
Thanks!
EDIT: I forgot to say that saving the current orientation before the activity A is destroyed and restoring it when it is created again is not an option too. Activity A should NOT be re-created after activity B finishes.
EDIT 2: I was thinking now and I realized that I could rewrite the question from another point of view.
I would like to avoid the re-creation of the activity A when it is resumed after activity B finishes.
Afaik, when the device orientation change occurs, a message is sent to ActivityThread (with value RELAUNCH_ACTIVITY). That causes the activity A to be re-created with the new screen orientation.
I want to avoid the activity A relaunch as that would solve my problems and would keep the last orientation it had.
I don't think it is possible to do this as you've described. When the user returns from the landscape activity to your previous activity you would need to lock the orientation to portrait (in order to ignore the landscape orientation that the phone is now in). Now, if the user rotates the phone, you won't see the rotation and you won't be able to change the orientation. Since you can't really tell whether the user just rotated the phone or if the rotation is due to returning from a landscape-only activity, you can't tell these 2 conditions apart.
However, assuming that you can somehow differentiate between these 2 cases, try the following:
If you don't want Android to recreate your activity on an orientation change (even only in certain circumstances), then you will need to tell Android that you want to handle orientation changes by yourself by setting
android:configChanges="orientation|screenSize"
in the manifest.
Now you'll need to implement onConfigurationChanged() to get the behaviour that you want. In the case where your activity has launched another activity with fixed orientation, you'll want to save the current screen orientation before launching that activity. When the user returns to your activity Android won't destroy it and create a new instance it will just call onConfigurationChanged(). When you get the onConfigurationChanged() call you'll need to check if the user just rotated the device or if this is the result of returning from an orientation-locked activity. In the case where this is the return after launching another activity you can then lock the screen orientation to the previous orientation by calling setRequestedOrientation(). In the case where the user just rotated the phone, you can then either:
Recreate the activity by calling Activity.recreate() Note: this only works if you are running on API level 11 or higher
Recreate the activity by calling your own method that basically does everything necessary to recreate the Views (call setContentView()) and reset your member variables as if the activity were recreated
Recreate the activity by launching your activity again: startActivity(new Intent(this, this.class) and then calling finish() to get rid of the current instance.
You, probably could store your activity's current orientation in shared preferences in onStop() and restore it in onResume()
I have developed an application and it contains web view.
My issue
When my phone's orientation changes from portrait to landscape the whole application loads again and the web view reloads showing the first page of website.
So I am getting confused about the screen orientation or saving the data during that phase, so how do I fix it...
Yes, in Android the Activity is destroyed and recreated when your change the screen orientation. Thus you need to restore your applications state on recreation. On way is to use the callback method onSaveInstanceState() which you can use to save the state in a Bundle.
The Activities are explained here: http://developer.android.com/guide/components/activities.html and I suggest you take a look on that page for examples and more detailed instructions.
The default behaviour is to restart the activity when a configuration change happens (such as orientation change).
To override this you need to tell the system you'll handle orientation change yourself by adding this to your manifest file in your <activity> element:
android:configChanges="keyboardHidden|orientation|screenSize"
You may also want to override onConfigurationChanged which will be called when such a change happens.
See http://developer.android.com/guide/topics/manifest/activity-element.html#config
The Android Activity lifecycle clearly indicates this behaviour .
What happens
Whenever you start an Activty is gets created(after onStart() method) the
onCreate(Bundle onSavedInstance)
The variable onSavedInstance mentioned above initially recieves null as nothing is saved.
But during the orientation the whole layout hierarchy has to adjust according to the new mode from an existing mode(from portrait->landscape or vice-versa).This change may remove the previous data that you had in your activity.So to avoid such a problem(loosing data), there is a method
onConfigurationChange(Bundle saveSomething)
This method will be called for you to handle some configuration changes into this,
The default implementation will save you some data like some text in an editText.
Note This method as far the specs goes should be used to save some trivial data.
Example
Suppose you had applied a background colour to the activty layout and now you rotated it default implementation won't save it but onConfigurationChange if you want you can save it like this
saveSomething.putInt("color",1);
Inside onCreate
protected void onCreate(Bundle onSavedInstance){
if(onSavedInstance!=null){
int color=onSavedInstance.getInt("color");
if(color==1){
setBackgroundColor(Color.BLACK);
}
}
}
Add the following line inside the activity element of your manifest file you will be handling the changes in configuration
android:configChanges="keyboardHidden|orientation|screenSize"
I have an activity. When I change the orientation, onCreate is called as we know. A new activity is created. But I want to continue with my old activity, is there a way to restore the old one and continue with it?
Use this in your activity tag
android:configChanges="orientation"
I know this question was already asked, but mine is a little different:
I have 2 different layout files for my game; one for portrait mode and one for landscape. When I rotate the screen, the onCreate method restarts my game (creates all the elements again). I donĀ“t want this to happen, so I wrote this line in the manifest:
android:configChanges="orientation"
It works, onCreate is not called, but the new layout is not being showed properly!
I tried to put the following code in my Activity, but it just keeps doing weird things:
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
setContentView(R.layout.gameview);
}
how can I fix this?
thanx guys
First of all understand how orientation changing in android works:
By default activity restarts on orientation changed event (and goes throw onCreate).
If you write android:configChanges="orientation" in manifest - it means it will not be recreated, but just remeasure and redraw view tree.
Comments about your code:
If you have different layout for different orientations - you have to recreate activity on orientation changed.
Method setContentView should called just once per activity lifecycle.
General way to handle this situation is:
Save game state in method onSaveInstanceState
In onCreate method restore game state if it is supplied (savedInstanceState param is not null).
Remove listening of configuration changing from manifest.
You should use onRetainNonConfigurationInstance() for save state and for restore state getLastNonConfigurationInstance() for any objects. Or hard-code set android:screenOrientation="portrait/landscape" in manifest.
The onCreate() method is called but the new Activity never appears. No errors are logged.
Follow up - There was no problem with calling startActivty() from a Fragment (we had a bug in the second Activity that caused it to exit immediately).
startActivity() from a Fragment works exactly like startActivty() from outside a Fragment.
A fragment should not be calling startActivity(), IMHO. A fragment should be telling its activity to display something, and the activity should be deciding how to do that. In some devices, that might be launching another activity. In some devices, that might be by adding a fragment. That decision should be made at the activity level, as it is the activities that are deciding what fragments go in what activities, based upon screen size.
Here is a sample application where a click on an item in a ListFragment causes either a separate DetailsFragment to be updated (for large/xlarge screens) or pops a new activity (for normal screens).
The problem was a bug in the second Activity that caused it to exit immediately. So to answer my own question, there is no problem with calling startActivity from a Fragment. It works exactly like calling startActivity from outside Fragment.