Android life cycle: Explanation for state transitions - android

I want to discuss the Android life cycle. I know the basics of how the Android life cycle works but there are some questions I want to ask.
Why don't Android apps move from running to stop directly why it first goes through the pause phase ?
Why don't Android apps move from Running to Destroy directly like IPhone apps? Why does it move from Pause->Stopped->Destroy why not Running->Destroy ?

Apps are not immediately destroyed mainly for performance reasons. From the Android Developer Activity Reference:
The Android system attempts to keep application process around for as
long as possible, but eventually will need to remove old processes
when memory runs low.
If the screen is still powered on and there's no pressing need for your device to free up memory, for example, it's obviously faster for the user if the activity is simply paused instead of completely destroyed. Multiple end lifecycle stages make this possible.
The various callbacks indicate different things. This allows you to separate your cleanup functions into the quick, critical items (disconnecting from system resources like a database or network connection) vs. the longer term tasks (persisting user data across launches of your application, for instance). Because your activity is kept around as long as possible, you can avoid the expensive operations when the user is just pausing the activity momentarily.
onPause() is the first callback, indicating your activity is no longer in the foreground. An app will be paused if a dialog appears or if the user pushes the Home button, for instance. If the app is paused for a dialog, for example, you wouldn't want it to be destroyed because it's still visible.
If you also receive onStop(), it indicates your activity is no longer visible. At this point the user no longer sees what you are displaying. This could mean the user opened another application, for example. Even at this point, however, the system may still keep your activity around to make it quicker for the user to return to it later. (If you/the user ended the activity, however, then it will not be kept and will proceed with the end lifecycle callbacks.)
onDestroy() is the final callback before the activity is destroyed. Note that in extreme cases, the system may destroy your activity without calling this method.

Related

How can we guarantee that onPause will be called?

Going of this question
android save game state in onPause or onDestroy?
The answer highlighted that the person asking the question should save game state in onPause because the onDestroy documentation says "There are situations where the system will simply kill the activity's hosting process without calling this method (or any others) in it, so it should not be used to do things that are intended to remain around after the process goes away." In these situations, how can we ensure onPause will be called? Is it possible to control what methods are called in these situations? Seems unpredictable
onPause will be called every time your activity leaves the screen, before it is finished or if something overlays your activity that keeps the user from interacting with your activity.
You don't need to worry that onPause is not called.
For more information look into the starting and stopping activity training or the Lifecycle Api Docs
You should save temporary instance state in onSaveInstanceState(). This method recieves a Bundle parameter which you can use to write state to. The Bundle is then sent to onCreate() when your app is restarted.
If you need to save instance state more permanently, then save it to a database or SharedPreferences. According to http://developer.android.com/training/basics/activity-lifecycle/stopping.html, you should use onStop() for more CPU-intensive operations rather than onPause(). I don't think you need to worry about onPause() being called in normal use cases. As far as I can tell, it is guaranteed. (Of course, there are always catastrophic failures, such as the user pulling out the battery of the device, but there's not much you can do about that.)
It's almost certain that onPause() will always be called. The reasoning is that it's highly unlikely the "system" will aggressively kill an active (i.e., visible) Activity.
In order to free resources, the Android OS effectively reserves the right to kill dormant processes - in particular ones that have been long-running but not recently used. In order for your Activity (and its process) to qualify for this, at some point you must have sent the Activity to a background state, e.g., pressed HOME or started another app's Activity. The simple fact your Activity is no longer visible means it will have been paused and onPause() will have been called. It's almost certain that the Activity will have been stopped and onStop() will have also been called.
What you have to remember is Android has been around for a while now and early devices had RAM measured in 100s of MB and the system behaviour possibilities and documentation reflects this. More recent devices have RAM measured in GB (even 10s of GB) so unless a user really pushes their device to the limitations of its resources, aggressive clean-up of app processes becomes less likely.
You can show Dialog for User to Act Accordingly.When Dialog will be opened to ask user that he wants to quit or not,Activity will definitely call onPause() and at this time you can write your game state saving code. Its better to write code on onPause() because at onDestroy() resources are freed by os.

Is it safe to do all cleaning up in onDestroy?

More concretely: Is it safe to place the canceling of a task in onDestroy? Also, is it safe to use onDestroy for unregistering receivers and freeing up resources?
My aim is to make sure that my task is canceled/destroyed when the Activity is destroyed, but not before.
onDestroy():
is called when the activity is destroyed and resources must be
released.
is NOT called when the activity is destroyed in a hurry (when the
system is low on resources etc).
The first case is clear: I do all cleaning in onDestroy and no problems arise. The second case is a bit of a problem though. When the Activity is destroyed and onDestroy is skipped (so I don't cancel my task), could it happen that the task continues execution, then completes and tries to update the dead Activity, so the app crashes?
We come to the real question:
When an Activity is killed and onDestroy is skipped, is everything attached to that Activity automatically destroyed? (Is onDestroy skipped only in case that everything will be wiped out altogether? Tasks, registered receivers etc)
If onDestroy is skipped does this mean that the whole app is being killed?
Let's focus on onDestroy(), because the solution is not in onPause() or onStop(). Arguments:
onStop() could be skipped when the Activity is being destroyed, just like onDestroy
onPause is called too early and too often, so it is not appropriate for the use case. Examples:
Screen lock: onPause can be called when the device screen is locked. Very often this happens like a screensaver and the user unlocks immediately because he is standing there looking at the screen. Canceling tasks and stopping everything my app is doing in such a case will only degrade user experience. I don't want my app to choke and misbehave just because of an incidental "screensaver".
In an example app I have two screens that are Activities. The user can quickly switch between them. In this app users tend to switch screens often and quickly.
Navigation: One of the screens has a map which receives location updates from the system. It records a precise graphical log of the changes in location (route), so it needs to run constantly until the Activity is closed. Normally I would register and unregister any receivers in onResume and onPause. However, this would make the app very unusable, as the updates on the map will stop every time the user navigates away. Therefore, I would like to unregister the receivers in onDestroy.
Loading list: The second screen has a list that shows data from a webservice. It takes 4 seconds to download the data. I use an AsyncTask and I know I should cancel when necessary. It should not be canceled in onPause, because it should continue loading while the user switches between screens. Therefore, I would like to cancel it in onDestroy.
There can be many more examples. Some of them might not be totally appropriate in everyone's opinion (you might even suggest using a service instead of AsyncTask). But the idea is important, and all of them have the same idea: keep on doing work that's specific to the Activity, while the Activity is paused, but ENSURE to stop doing it when the Activity is destroyed. (It does not matter whether I am using an AsyncTask or a Service. In either case, the work should be stopped when the Activity is destroyed.)
P.S. If the answer is that it is not safe to do the clean up in onDestroy, this would mean that the Android framework requires us to stop everything we are doing in onPause. And then I would not see any reason for using onDestroy...
I would like to refer you to this baby: http://developer.android.com/reference/android/content/ComponentCallbacks2.html#onTrimMemory(int)
Essentially it gives you all the places where the system finds it useful to cancel tasks and clean its memory:
Please take a closer looks at the following 2 cases:
TRIM_MEMORY_UI_HIDDEN - the process had been showing a user interface, and is no longer doing so.
TRIM_MEMORY_COMPLETE - the process is nearing the end of the background LRU list.
Which are the cases for most of what you asked.
In the same method you can also catch TRIM_MEMORY_RUNNING_CRITICAL which will alert you to a case where the system has no memory and special actions must be taken immediately.
This method has made my development life much better in similar cases.
If you just need to do some cleanup, no matter how the activity is closed, you should be able to use a combination of onSaveInstanceState() and onDestroy(). One of those should be called no matter what. Maybe have a boolean cleanupDone in your activity, which is set whenever one of the two finishes.
Concerning saving of user data, have a look at Saving Persistent State:
Google suggest a
"edit in place" user model
That is: save as soon as the user creates new data, at the latest in onPause(). This does not mean that you need to recreate the data in onResume(), just that it should have been saved.
By the way: onStop() can be skipped only on pre-Honeycomb devices, that is, as of June 2015, less than 6 % of all devices. Still, onSaveInstanceState() should be called if either onDestroy() or onStop() are omitted.
As far as I gone with android,
1 When your apps crashes every resource relevant to it are destroyed.
2 When the device changes configuration resulting the Activity to be destroyed and recreated.
3 When apps running in background and Android kill it due to running on Low Memory
apart from these the other callback method are called i e
1 when another Activity come in front , or your device locks ..etc
In all case according to your requirement you can release all your resources in onDestroy and cancel the Thread and Asyntask and stop all the services etc .if you want your task remain paused and alive while on destroy called then you can save the configuration and retain it while onCreate is called again by check is null or not.

Android multitaksing

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.

Android Memory Management for Lifecycle

I am trying to determine how to keep my app safe under various Android lifecycle conditions, such as another app being start, phone going to sleep, etc. I understand the lifecycle states and the event methods I can hook into, but I am not sure how memory is handled in regard to things I already had references to. I am well aware that my app may be killed at any time if the OS needs to, but what about individual references? Here are a few example scenarios: if my app is running and the user gets a phone call, or the user starts another app, or the phone goes to sleep. Assuming my app did not get killed, can I safely use my references or will I get random null pointers? I guess what this comes down to is... does Android either kill or not kill and app or will it reclaim some memory (where there are still valid references) from an app without killing it?
Most of the time when the user switches to another app or answers the phone, you app will simply be suspended. When it comes back, onResume() will be called and it will continue on it's way with no issues. References and that kind of thing should be fine. It is recommended that you unregister listeners and re-register them in onResume(), though.
You should always remeber that your app may also be completely killed at any time, so save your data.
The truth is most of the time the application will not get killed in a brief interruption, for example a call or email, but if you want support these situations you should preform cleanup or saving the data in onPause(). When the application comes back it will execute onResume().
References will not disappear until the activity is destroyed, do not worry about NPE in the pause -> resume scenario unless you are doing something very odd.
If you are using listeners or GPS, you should unregister during onPause() and resume it later.

If my application goes to background, it still continue working? (sending/getting data from internet)

i am working on an application that send and get data from internet each 5 min
if i press home key and my app goes to background... it will still continue sending/getting data from internet? or i have to do something special?
thanks
"If an activity is completely obscured by another activity, it is stopped. It still retains all state and member information, however, it is no longer visible to the user so its window is hidden and it will often be killed by the system when memory is needed elsewhere. If an activity is paused or stopped, the system can drop the activity from memory by either asking it to finish, or simply killing its process. When it is displayed again to the user, it must be completely restarted and restored to its previous state."
http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle
No. Activities shouldn't be depended on to process tasks in the background.
The following link illustrates the fundamentals of different Android components and what they do, i.e. the "parts" of an app.
You should be using a Service for background processing.
From what you're saying, I'd suggest an IntentService fired by an Alarm.
Application Fundamentals

Categories

Resources