EDIT: Solution to this question is - Android - Query regarding activity lifecycle on changing screen orientation
I'm starting Android development and am facing problems regarding activity lifecycle. I have an Activity A that calls Activity B in its onCreate() method (Activity B has a custom grid view inside a relative layout).
When in Activity B, if the screen orientation remains unchanged and back button is pressed, as expected it goes to Activity A's onResume() method. However, on changing screen orientation while in Activity B, on later pressing back button, it goes to Activity A's onCreate() method thereby recreating Activity B (as Activity A calls B in its onCreate()). Only on pressing the back button twice does it go back to Activity A's onResume() method. How do I ensure that on changing orientation, I go to Activity A's onResume() by pressing back button just once?
I've tried including:
android:configChanges="keyboardHidden|screenSize|orientation"
in Activity B in manifest and hence this avoids calling Activity B's onCreate on changing orientation but it still doesn't solve my problem.
Activity A is base, all onResume and onBack work with it, End.
On head of that you start Activity B, with it's onResume and onBack classes.
On rotation, B is re-created, not A, since you are in B.
I think you must change the way you start B.
Or onResume of B, finish() B. then in onResume A start B again.
I found the solution to this. Since the screen orientation had changed while in Activity B, Activity A was getting recreated (different orientation than earlier). So all that was needed was to add
android:configChanges="keyboardHidden|screenSize|orientation"
to Activity A in manifest.
Related
I have researched numerous posts regarding Activity back stacks, as well as the Android Developer website, but still can't find a solution to a problem I'm having.
Scenario:
I have Activity A, I navigate to Actvity B, from A and then press the back button to go to Activity A again:
Actvity A --> Activity B --> Actvity A
Nothing out of the ordinary..
Problem
When I press the back button to go to from Activity B --> Activity A, Activity B is not destroyed straight away, as expected it goes into a pause state and this is where I have strange problem. If I want to return to Activity B from Activity A and IF Activity B is still in a pause state all its life cycle methods are called when use startActivity(B) from Activity A:
Activity B - onCreate() > onPause > onStop > onDestroy <-- why is this happening
At this point, to me it shouldn't exist anymore, and I can't explain why it went through all its lifecycle methods, rather than just the start initialisation lifecycle methods. The fall out from this strange behaviour is that the Activity is still visible on screen but doesn't populate a RecyclerView which in first initialisation did so as expected. At this point if I press back Activity B enters a pause state again.
If Activity B is in a pause state (Activity A is at top of stack) and the framework ends Activity B through lifecycle callbacks and I navigate to Activity B again from A it works as expected (RecyclerView is populated), basically a fresh instance always works fine.
All I can assume, when referring to the Activity Lifecycle diagram, is that Activity B enters a pause state, however is destroyed without calling onStop, onDestroy etc.. meaning any Activity clean up operations I have in those callbacks aren't happening?
Things I've Tried
Changing various Intent filters, and combinations, when starting Activity B:
FLAG_ACTIVITY_NEW_TASK
FLAG_ACTIVITY_CLEAR_TOP
FLAG_ACTIVITY_SINGLE_TOP
Calling finish() when onBackPressed() is called in Activity B
Various other fingers crossed and hope changes, nothing seems to work.
Can anyone help please!
Ok, so I found the answer to the problem - not obvious at first, but now I understand what was happening.
The root cause of the problem was to do with 2 instances of the same Activity (Activity B) referencing the same Objects (Objects supplied from DI library).
Firstly when returning to Activity A from Activity B, Activity B was not immediately destroyed, and this causes a complication - this instance would never be reused, however still existed for a period of a few seconds. In this situation when using startActivity(B) from Activity A it would create a new instance and destroy the old (hence why I was seeing logging in both creation and activity ending callbacks), if it still existed. In this scenario both instances were sharing the same object, and this object "cleaned up" the Activity when destroyed. So the object (Presenter in this case) was being told by the old instance that it should clean up the Activity as its being destroyed, however this was not the case, because a new instance had been created.
The solution
Quite simple really, every time a new instance of Activity B was created, store in the Presenter a unique number (startId), and when Activity B called onDestroy() pass its current unique number, and check they match - if they don't match its not the latest instance, so do nothing. Very similar idea when you want to stop a Service, and check its the latest Activity calling the service from the startId.
Personally I don't know why Activities aren't destroyed straight away on pressing back, but thats the reason why this was happening.
I have 2 activities, activity A and activity B. Both the activities have fragments. Activity A calls activity B.
When activity B is called and I press back button, on medium screen size the following function sequence is called.
onResume() of activity A.
but when activity B is called and I press back button, on large screen size (10.1') the following function sequence is called.
onCreate() of activity A.
onCreateView() of the fragment associated with activity A.
onResume() of Activity A.
Both the activities are restricted to portrait mode in the manifest and I also used
android:configChanges="orientation|keyboardHidden|screenSize"
for each activity in the manifest.
What I want is, that the application behave like it behaves on the medium screen size. i.e i don't want onCreate() of activity A to be called when I press the Back Button.
Any help will br appreciated and thanks in advance.
Save your activity state in onsaveinstancestate() then check for the bundle before all the onCreate code.
http://developer.android.com/training/basics/activity-lifecycle/recreating.html
I wrote an Android app with several Activities and a Main Activity. When I go from the Main Activity to lets say Activity B, I want to "pause" the Main Activity, when the back button is pressed it should go back and reactivate the Main Activity instead of calling onCreate().
This shall work with all Activities, so if I click on a button to start Activity B, it shall also reactivate the old Activity B instead of creating a new state with onCreate().
How can I realize this?
PS: I already tried it with parcelable, but this do only work, if I close the application or something unexpected happens.
It's always possible that the first activity may be destroyed when you start another activity. It will be recreated when you go back to it. Every app should be written with this possibility in mind. To make sure your activities can handle being destroyed and recreated, turn on the "don't keep activities" developer option.
It is by default in Android. If you Start Activity B from Activity A then activity A goes in stopped state. Below methods will be called of Activity A
onPause()
onStop()
When you tap on Back key on Activity B. Below methods of Activity A will be called.
onRestart()
onStart()
onResume()
For reactivating Activity B, you can set Activity B launch mode as singleInstance. This will make sure that only single instance of Activity B will be created. onCreate will be not be called again. onNewIntent will be called when that activity is reactivated.
Refer: http://developer.android.com/guide/topics/manifest/activity-element.html#lmode
Activities live in stack order. Each activity has its life cycle. When you close an activity (Activity B in your example) it eventually reaches onDestroy() method and removed from the stack order. It is by default in Android and there's nothing you can do about it.
What you can do is rewrite the onStop() method in Activity B and save some activity data (like text in EditText, for example) in SharedPreferences - read here. Then in your onCreate() method you can call for SharedPreferences, check if it's not empty and restore the text in the EditText by pulling appropriate value by key.
I have two activities A and B. in A I start B activity. In B acitivity when user press back button I need to update A's layout values. So I need to know
In acitivity A which function will be called when return back to activity A.
try and override onResume() function in A. works for me.
Take a look at the Android life cycle: http://developer.android.com/reference/android/app/Activity.html
You will see that when you return to Activity A, function onResume() will be called.
A key point when learning Android API is the Activity Lifecycle.
When an activity is displayed : it's onResume() method is called. So it will be called:
when the Activity is displayed for the first time (after onCreate(...))
every time the activity came to front
after activity re-created (for instance, after screen rotation)
For more details read this : activity pausing-resuming and more global overview of the lifecycle.
The Activity javadoc is also very good resource
As I understand it, if I don't explicitly tell Android that I want to handle a configuration change in an Activity, it will get torn down and re-created on, say, an orientation change.
Let's say that I have object O that's an instance of some class MyCustomClass in Activity A. When the user presses a button in Activity A's layout, we call O.startActivityB. That method will start Activity B. When Activity B gets re-created on an orientation change, I can tell (some flag was set in another or something), so Activity B immediately runs this:
setResult(RESULT_CANCELED);
finish();
return;
Who is Activity B's parent activity at this point? Who gets the result code?
If you started Activity B from Activity A, the 'parent' is Activity A. The fact that an activity gets recreated for some reason doesn't change the activity stack in any way. BTW, if you want to receive a result, you need to use startActivityForResult(), not startActvity().