Scenario:
An Android app has an Activity with a Fragment.
The user sends the app to the background by pressing the home key.
Two hours pass, the Android OS kills the process to free up resources.
The user switches back to the app through the Recent Apps List.
The onCreate method of the Activity will now find the existing Fragment by using fragmentManager.findFragmentByTag()* as best practice cites. Yet, adding this old fragment to the activity will not make the fragment render. I'm unsure if I'm doing something wrong, or this is simply not a supported use case for reusing old fragments.
Must I implement special handling of this scenario (i.e. new up the Fragment instead of reusing the old)? If so, what is the best practice of detecting that the process has been killed and relaunched in onCreate?
edit 1: *) I am testing this by using DDMS to kill the process. This might not emulate the OS' way terminating a process correctly, as for instance onDestroy() is not called. Does anoyone know if the old fragments are disposed from the FragmentManager when onDestroy() is invoked by the OS? If this is the case, this question is moot.
No, You can't reuse a Fragment once the process is killed. Once the process is killed, you app no longer exists on Android main thread, hence a new instance of the activity has to be launched.
Your app starts with an your main activity as in Manifest file, and loads corresponding views and fragments. Please go through the Activity Lifecycle of the Android, to know more about it.
This teaches you how to maintain your activity run in background and when not in use:http://developer.android.com/training/basics/activity-lifecycle/index.html
Related
I want to understand and simulate when does Android call onDestroy() of my activity, without destroying the entire process. I'm not calling finish(), and I want to make Android destroy my activity on it's own.
From the activity-lifecycle documentation:
The system never kills an activity directly to free up memory. Instead, it kills the process in which the activity runs, destroying not only the activity but everything else running in the process, as well.
But the Android Activity documentation says:
This (onDestroy) can happen because [...] the system is temporarily destroying this instance of the activity to save space.
So which one is it? Does Android destroy activities when it's low on memory, or does it only kill entire processes?
I want to simulate a situation where Android kills the activity without killing the entire process.
I can mimic this by using the "Don't keep activities" developer-mode setting, but I want to understand how can this happen in the real-world.
I want to make Android destroy my activity on it's own.
Android does not do that, other than through your actions (e.g., finish()) or user actions (e.g., BACK navigation, configuration changes).
So which one is it?
The former (Android kills processes, not activities). See this answer from the woman who wrote this stuff. FWIW, also see this decade-old blog post of mine.
I wrote a small game on android. It has one activity + one fragment. I save the state of the game in Fragment.onSaveInstanceState and restore the state in Fragment.onCreateView.
If I rotate the screen, the game state is preserved properly. However, if I turn off the screen and come back to the game at a later time, sometimes I lose the game state and get a new game instead. Therefore, I wonder if Fragment.onSaveInstanceState is called at all when the system decides to kill a process to recover memory. Also, what is the life time of the stuff that gets saved into the Bundle in Fragment.onSaveInstanceState?
By the way, is there anyway to easily test such a case during development? It'd be terribly inefficient to wait for a day or two for the system to kill it.
Thanks for helping me out!
I wonder if Fragment.onSaveInstanceState is called at all when the system decides to kill a process
Yes.It is called.
I think your issue lies somewhere here.From the documents :
The most significant difference in lifecycle between an activity and a
fragment is how one is stored in its respective back stack. An
activity is placed into a back stack of activities that's managed by
the system when it's stopped, by default (so that the user can
navigate back to it with the Back button, as discussed in Tasks and
Back Stack). However, a fragment is placed into a back stack managed
by the host activity only when you explicitly request that the
instance be saved by calling addToBackStack() during a transaction
that removes the fragment.
Not sure if this can solve your problem but i think you should keep it in mind while writing your game code.
First of all, I'm new in android developing...
I had read some article in android API guide and feel confused about the component life cycle with the hosting process.
Here is my understanding:
Android system may kill some activities in a process or the whole process in low memory situations,which means there is a possibility that a started activity may die, but process still alive.
If a service is started and not call any stop method, when in extreme low memory, this service is killed by system with its hosting process, not just the service itself, means this circumstance should not occur:service is killed by system, but hosting process still alive.
When an app starts, the user navigates activity1 -> activity2 -> activity3 and none of them call finish(). Next, the user navigates to another app's activity and plays with it so long that the former app process is killed by the system. Now the user navigate back to activity3 in the back-tracking stack, what will happens? The former app process restarts with only activity3 recreate?
Anything wrong ?
There is no need to switch to another app's activity: from the moment that you leave the first activity to go to the second activity; there is a clear possibility that the first activity might have been destroyed when you return on it from the second activity (back-tracking) and when you go to a third one, either the first one, the second or both of them can be possibly destroyed in the mean time. In fact, you don't even to leave an activity to see it destroyed; as this will automatically happen simply if you switch from the portrait mode to the landscape mode and vice-versa by rotating the device.
When you return to an activity, the onRestart() function will be called if the activity has not been destroyed in the mean time. If it has, the "onCreate(Bundle savedInstanceState)" will be called instead but with the argument "savedInstanceState" set to a non-null value (ie, it will point toward a valid Bundle object) if you have took the precaution of saving the current state of the activity in the "onSaveInstanteState(Bundle outState)" function when the activity has entered the process of being destroyed by the system. The system will always call this function before destroying an activity when this one need to be restored later for back-tracking. Of course, it won't be called after a call to finish() because this will also remove the activity from the back-tracking stack.
Finally, in Android, the coupling between activities in the same application is very loose. When it comes to the use of resources, there is not much of a difference between switching to an activity from the same application or from another application. In many ways, activities will behave like if there were all fully independant applications when it comes to running. This is why you always need to use an intent to start an activity; even when it is from the same application.
Based on my understanding ...
In android during low memory situations, first activities would be removed from memory where the onDestroy method gets called.
This is not the case always. It depends on how the service is started i.e whether from onStart or through Binding the service with a component.
Once the former app process is killed, then when the user launches the application, he will be taken to activity 1. Launching the activity in same task or different task depends on launch modes used (single task, etc)
I have a Singleton class which I use with the one of the activities of my application.
When I exit the activity - which brings me back to the menu activity - and then reopen the activity I find that when I try to access the singleton it is still the same.
Surely it should have been destroyed with the Activity?
I saw the question here: living singleton, when activity end
but could not quite follow what they mean.
When I press the return button on my device (or use finish within the Activity itself) is the Activity kept alive for future use? If so, then that would explain it.
Surely it should have been destroyed with the Activity?
No.
When I press the return button on my device (or use finish within the Activity itself) is the Activity kept alive for future use?
The activity is not. The process is. Singletons are part of the virtual machine and will live as long as the process does. Exiting the last activity does not immediately terminate the process, so the singleton lives on... at least for a while.
Android will eventually terminate that process to free up memory for other apps. How quickly it will do that depends on what the user is doing, what apps are installed, phase of the moon, etc.
I am seeking short characteristic of Android Multitasking. I have found, that when you minimize Android application, it is ended and it's process remains on the background. When user wants to reuse his app, this process alive it's application. User will be at the same state, when he left (if there was enough memory while working with it), or it will be loaded from scratch, because there was no free RAM for other work and Android exited this process. Am I right? Everywhere there are articles with 20 pages and more about Android multitaksing. I need to know key points because I am lost in a such long artices.
Thanks
Short Answer: Yes. If your app can live in memory despite being 'closed' then it will stay in RAM and processing will continue when you click on it again. Otherwise it will be restarted and you will get an onResume().
Long Answer: Please just read the Activity Lifecycle:
When Android activity is covered by other windows it will enter into paused state and method onPause will be called. It may also me destroyed by OS and then onDestroy will be called. You have very little control over it and can't expect your application to come back up with the same state. However, when activity is brought up again to foreground in will go through steps of onCreate and onPause. Those methods can be used to restore its state.
Here you can find nice diagrams describing Activity lifecycle. Similar but slightly different lifecycle is applicable to service.
http://developer.android.com/reference/android/app/Activity.html
Android activities are the main visible screens that user see while the application is running. If you close the screen or switch to another application, the current activity is put to hibernate and you can save the state with
Activity.onSaveInstanceState(Bundle bundle)
After your activity gets the control back, you can restore the state with
Activity.onRestoreInstanceState(Bundle bundle)
Note that you need to be careful not to store any context references within the activities and related classes as the activity and thus context has changed between pause and resume. Instead, you should always pass the current activity as the active context to avoid having exceptions from invalid context.