I am trying to mantain a log , when exits the applicaiton. I have used this code :
public void onDestroy() {
super.onDestroy();
Log.d("D", "Destroyed");
}
But this only works when I press the Back button. When I press Home button , the application Pauses , and If I close this application from task manager , then the onDestroy function is not called. How to handle this ?
Any idea ?
You can't handle the closing of application from task manager. In this case you're killing the app and onDestroy isn't called. You should make all clean up in onPause
You can do your stuff in onPause() method.
In your case:
If End Process is used from Process list in task manager, then nothing is called in application, the application is simply terminated.
If End Task is used from Applications list, then WM_CLOSE is sent to the window, which in turn allows application to do the cleanup.
onDestroy() is called when an activity finishes its life cycle. It is also called once in the lifecycle of an activity.
The OS decides when things "go away." The onDestroy is there to let your app have a final chance to clean things up before the activity does get destroyed.
From the Android Developer Guide:
There are a few scenarios in which your activity is destroyed due to
normal app behavior, such as when the user presses the Back button or
your activity signals its own destruction by calling finish(). The
system may also destroy your activity if it's currently stopped and
hasn't been used in a long time or the foreground activity requires
more resources so the system must shut down background processes to
recover memory.
When you switch between apps by pressing the home button, Android pauses the activity and resumes it when you return to the activity.
For the most part, the OS decides when to quit an application so it wouldn't make sense for you to log when an activity is destroyed. I would suggest overriding the onPause() or the onStop() method
Related
I wanted to ask about the activity's lifecycle.
If an activity is going to the background, or the user pressed the home button so the application itself is not visible anymore, the onStop() is called, but not always destroyed.
1) when the above happens, what actually happens to the activity? Does it move to the backstack? or something else?
2) specifically related to the first question - when will the onDestroy() method be invoked in a case where the activity has already stopped, but the onDestroy() wasn't yet called at that moment of stopping?
3) generally about onDestory() - I know onDestroy() is called when the system doesn't have enough resources anymore, or when Android is destroying a portrait/landscape layout in order to load the other one. When else can it be called?
1) when the above happens, what actually happens to the activity? Does it move to the backstack? or something else?
Suppose you have pressed the home button and the current application will be moved to the background state, now the object of the current app activity will be stored in the TASK and this task has all the objects of the activity of the application. So this TASK will be in the memory and the Android System will kill this task only when there is shortage of the memory or any user manually kills the app or finish() method is called.
2) specifically related to the first question - when will the onDestroy() method be invoked in a case where the activity has already stopped, but the onDestroy() wasn't yet called at that moment of stopping?
onDestroy() will only be called in the following possibilities
User manually kills the application.
Android System will reclaim the memory where there is shortage.
When finish() is called in the code itself.
Hope it helps.
When you're in an an Activity (we'll call it A), and you invoke a subsequent Activity (B), perhaps as a result of clicking a button in A, and then RETURN to that prior Activity A, either by clicking the Back button or explicitly calling finish() from within B, it causes A to be completely rebuilt, calling its constructor and its OnCreate() method, etc.
Is there any way to prevent that from happening, so that it actually does return to the prior, already existing, Activity A?
Correct me if I'm wrong, but it should not call onCreate() here's a gross over simplification, but let's say activity's are managed much like a simple stack, let's call it AppStack
When a onCreate() for Activity A is called, the OS pushes the Activity Instance onto the AppStack
________ _________________
Activity|
___A____|_________________
When you click a button on Activity A, it launches a new intent to Activity B
Intent actB = new Intent(this, ActivityB.class);
and subsequently puts Activity A into Stopped state
When Activity B's onCreate() is called the OS pushes that Activity Instance onto the AppStack
________ __________________
Activity|Activity|
___A____|___B____|_________
Now if you call finish() or super.onBackPressed() in Activity B, the OS will pop() the Activity from the AppStack
________ __________________
Activity|
___A____|__________________
When the OS returns to the previous activity, it sees that it is Stopped and begins the process of Resuming it through onResume().
Now if there is some data that you require to be persistent, you can add it in by Overriding onResume()
Check out the activity lifecycle docs, for more info:
This is by design:
If an activity is paused or stopped, the system can drop it from memory either by asking it to finish (calling its finish() method), or simply killing its process. When the activity is opened again (after being finished or killed), it must be created all over.
See Activity Lifecycle. It's also why the Service class exists:
A Service is an application component that can perform long-running operations in the background and does not provide a user interface. Another application component can start a service and it will continue to run in the background even if the user switches to another application.
It's not a typical scenario but when onCreate() is called when going back to that activity that means the Android OS kills it in the background.
Reason: Android is experiencing some memory shortage so killing some of the background task will be a must.
Is there any way to prevent that from happening?
No, you don't have a control over it, there are many reasons why its having a memory shortage e.g. other app installed that certain device is consuming more than expected. Although you can handle this use-case by storing the current information in onSaveInstanceState() and recovering the value from onCreate().
Calling finish() on ActivityB or pressing back will just destroy ActivityB.
ActivityA will not be completely rebuilt. This means it will not call onCreate method. It will just call onResume.
This is the normal behaviour.
However, on special situations, the system could destroy ActivityA (maybe because it needs memory to perform another task), so when you go back to it, the system will have to rebuild it.
To simulate this situation, there is a setting that you can check/uncheck, called "Don't keep activities".
If you have it checked, you will be simulating the situation explained above, it will always destroy the ActivityA as soon as it is not shown, and when you come back to it, the system will have to rebuild it calling onCreate.
I have implemented ActivityLifecycleCallbacks in a private class inside my Application class.
If Home button or Back button is used, lifecycle's onStop() and onPause() methods are getting called. If I kill the activity by swiping out from background, onDestroy() method is not getting called. It gets called when I start my activity next time. I am using moveTaskToBack(true) in case of Back press.
What must be the issue and which lifecycle method should get called when we swipe out from background?
From the documentation of onDestroy():
Note: do not count on this method being called as a place for saving
data! For example, if an activity is editing data in a content
provider, those edits should be committed in either onPause() or
onSaveInstanceState(Bundle), not here. This method is usually
implemented to free resources like threads that are associated with an
activity, so that a destroyed activity does not leave such things
around while the rest of its application is still running. 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.
Such a situation is swiping the app out of the recent tasks list.
Check out this answer on how to get notified when the app is getting swiped out of Recents.
I remember reading a similar question on StackOverflow. Here was the top answer:
Handle exit application from Task Manager
Handle exit application from Task Manager
Unfortunately there isn't a good answer for handling this situation. If the app is force-killed, onDestroy method isn't necessarily called. According to the documentation.
Note: do not count on this method being called as a place for saving data! For example, if an activity is editing data in a content provider, those edits should be committed in either onPause() or onSaveInstanceState(Bundle), not here.
If you can, clean up in the onPause() method. In order for the user to get to that screen to kill the app, it has to have been backgrounded and thus onPause() would be called. (see documentation)
swiping app from back ground i.e. clearing from recents causes the whole process and task to be killed and that time onDestroy() may not be called , when user presses back from an activity then only that activity is killed not the process.
I have an Android existential question:
Does an App's onDestroy() get called when I kill it by swiping it out of the task manager?
If not... how can I detect a "killing" swiping event on the app, and do some final stuff beore it dies?
onDestroy()
Perform any final cleanup before an activity is destroyed. This can
happen either because the activity is finishing (someone called
finish() on it, or because the system is temporarily destroying this
instance of the activity to save space.
Note: do not count on this method being called as a place for saving data!
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.
Instead, rely on onPause() and onStop() to do any final work before your app goes out of view.
Is your main concern the "swiping" event or just saving data? :)
On start my app displays a splash screen and checks via network if the current user is still premium.
My problem: I started my app right before I went to bed and minimized it by pressing the home button. In the morning I launched the app again and it resumed the activity from the night. The app never really quit, my splash screen was not shown and and it couldn't check if the user is still premium.
So how can I achieve my app to be closed after a certain time (e.g. when the app is minimized)?
You should write the Premium user check logic in your onResume() method so that
if the activity is in pause or background state it will check the
logic every time it will be launched .
Don't try to finish app when it's minimized. Use Activity lifecycle callbacks.
#Override
protected void onResume (){
//check for changes here
}
If you want to end an activity, you call finish(). So you could record the time in onPause, then in onResume, check how long its been. If its been too long, call startActivity on your main activity, then call finish() to end the old one.
I think you should become more familiar with the Android Activity Lifecycle and think about which call back in your activity should you check if the user is premium