I'm trying to get the main activity for my app to finish (not remain an active application in background) while keeping the process alive for a service.
If the user presses the home button and leaves my app or another activity is launched from outside of my app, I want the activity to be closed and NOT listed as an active application.
It is important, however, that the process stays alive. I don't want my background service to die as well.
What's the best way to go about doing this?
You should not forcibly close the application as the system does well in handling this itself. Instead you should call finish() to signal that the app is done and can be disposed of(your service will continue running).
By default Services don't have a UI. Once started they run until they crash or are killed . The user can close your app and launch a new one and the Service will persist.
Activities on the other hand are only running when they are visible. When the user navigates to another activity the previous activity is paused, stopped, or killed.
A simple way to do what you've briefly described above would be to create an Activity that starts a Service. That way when use navigates away form your Activity the Service will keep running in the background.
If you want your activity to die completely whenever a new Activity comes into view simply put a call to finish() in the onPause() or onStop() methods for your activity (which ever is more appropriate for your app).
Related
My Android application exists of a main activity in which the user has the ability to start several other activities. In order to have a permanently working keyword recognition (speech recognition), I use an IntentServicethat is started in the onCreate() of the main activity. The service needs to be working as long as any activity of the app is in the foreground.
However, this service uses the microphone all the time, so it's desirable to stop the service once the user returns to his/her home screen. I know the basics about activity lifecycles, but my question is: what is the best way to stop the IntentService when the user returns to the home screen from any activity?
To restart the service when the app is re-opened, I was thinking of a superclass that all activities inherit from. In the superclass I would set a static boolean serviceStopped that is set to true when the user goes to his/her home screen (and the service is stopped). In the onResume() method, this boolean will be checked and the service will be restarted if needed.
As I know there is no way to detect if the user leave your application and is in the home screen.
I think there is no a simple way to detect if your application is open/closed; however I found this How to get the list of running applications? and I think it could help you.
You could also try to start a Service in the background and check when any of your activities start or is destroyed.
Lets say an application is running with activity B is in top of the stack and activity A is the activity that has the launch intent defined in the manifest. Then my app goes in the background (not visible) and the system temporarily kills my application and brings it back up again.
At that point which activity does the system bring up first, activity A (launch intent defined in the manifest) or activity B ?
Also if the application is temporarily killed then does it restart right away or it might be dead for a while?
My application has a lot of dynamic state, it also logs in to a server, so when the application is temporarily killed then the state of my application can change during that time and when it is restarted I will again have to start my application and re-login and update all its state again. Is there any way this can be avoided?
Thanks.
Sure, If application is killed then it should start from launch activity. If there is login option, then you should keep remember me option too, so that if app is being killed you got the state of app and execute auto login if remember me is set otherwise just launch the app with login process.
I beg to differ from what #Keshav says. I think the Activity that was destroyed last is what is re-created and shown to the user. I base my belief based on what happens when the configuration of the device changes - the current activity is actually destroyed the same is re-created and it's not the very first activity that was launched.
As far as what you should do, guidelines when your app gets terminated or destroyed while it's in background, you have to refer to:
http://developer.android.com/guide/components/activities.html#SavingActivityState
You wrote:
Lets say an application is running with activity B is in top of the
stack and activity A is the activity that has the launch intent
defined in the manifest. Then my app goes in the background (not
visible) and the system temporarily kills my application and brings it
back up again.
The following happens:
A new process is created for your application
Your Application object is instantiated and onCreate() is called on it
An instance of ActivityB (the top activity on the task stack) is instantiated and onCreate() is called on it
Your root activity (ActivityA) will only be instantiated when (and if) ActivityB ends (is finished or the user presses the BACK button).
You cannot prevent Android from killing your app while it is in the background. However, you can determine that this has happened and react accordingly. The easiest way to do this is to have a static member variable *either in the root activity or in a custom Application class) that you set to true when the root activity is created and has performed its initialization. In onCreate() of ActivityB, check if this variable is set to true. If not, your app has been restarted, so you can now react. For example, you could just redirect the user back to the root activity and force start your application from the beginning. Or you could tell the user to wait while you reinitialize your application, etc.
Firstly, sorry for my English if it's not enough good. I'm having some problems in my application.
Starting, my app has multiple activities and one service which works in background since the first activity execute it. If I press back button on my root activity, I exit from the app but the service continue working. Then, I go into the app back, and the service work perfectly. My problem comes when I press a button to exit the application (there, I stop service and finish the root activity mainly) and then exit without any problem, when I want to enter the app again, the service is started, but if I want to change to another activity (which doesn't have the serviceConnection) my service get called onDestroy() method without any reason for that. I don't have how to continue, because the usual way to execute in this case is the service go on working as the first case.
Thanks a lot.
There is for sure a reason why onDestroy gets called.
In the first section of 'Services' in the developer guide, you can read the following:
Multiple components can bind to the service at once, but when all of
them unbind, the service is destroyed. (link)
So, if all components unbind from the service, the service will get destroyed. When you enter the activity that is not bound to the service, the service will be destroyed.
I'm wondering why you don't want your service to be destroyed since you don't need it in your 'another' activity?
I create a new thread in an activity and I rely on onPause() to interrupt the thread. If my app crashes, or the Activity somehow ceases to exist, I want the thread to be killed.
Is Activity/Fragment.onPause() guaranteed to be called when an Activity is no longer running? If not, how can I guarantee the thread in question is killed?
If my app crashes
onPause() is not called here, but this shouldn't bother you as your entire app process ceases to exist, inclusive of all threads you have created (UI or otherwise).
Activity somehow ceases to exist
onPause() will be called whenever your Activity is moved to the background from the foreground, which is done in every conceivable way in which your Activity can be shut down, except for your app crashing. However, as I mentioned above, the app crashing will also by default kill your thread.
onPause() is essentially called whenever your Activity is no longer in the foreground. Your Activity may still be alive and in memory after onPause() has been called, but there is no scenario which I can think of in which your Activity is alive and in the background without onPause() being called.
Yes , onPause() will be called when an activity is no longer running. Suppose an activity is closed then the sequence of events will be onPause() -> onStop() -> onDestroy(). Even if your activity slips into the background when another activity starts or when the screen switches off, onPause() is always called even if the other two methods aren't called. So even if activity ceases, onPause() will be called and your thread will be killed.
But when your app crashes, along with your entire activity, even the thread that you have started will be taken care of by Android by finishing it all.
Suppose you have two activities A and B. You navigate from A to B. Activity A goes to background ie activity A is paused. Activity B takes focus ie foreground. When you click back button activity B is popped from back stack and activity A takes focus ie activity A resumes.
When you display a dialog in activity the activity in paused and dialog is displayed on click of back button dialog is dismissed and activity resumes (foreground).
When activity is no longer running it is in background so it is paused. I agree with Raghav Sood to what happens when app crashes.
You should usually use the onPause() callback to:
Stop animations or other ongoing actions that could consume CPU.
Commit unsaved changes, but only if users expect such changes to be permanently saved when they leave (such as a draft email).
Release system resources, such as broadcast receivers, handles to sensors (like GPS), or any resources that may affect battery life while your activity is paused and the user does not need them.
Note :
Multiple tasks can be held in the background at once. However, if the user is running many background tasks at the same time, the system might begin destroying background activities in order to recover memory, causing the activity states to be lost.
In addition to the accepted answer, which helped me here, I would like to add that there exists a way to basically, catch any error or crash that happens. This allows you to do things before the app exits. For example, you can save the whole logs, in order to send it later to a remote server for debug.
This means you can also probably do other some kind of light computational things if you really needs to (properly closing active connexions, etc etc).
How can a user destroy a service outside of the app. I made an app that the user can never "Exit" because the main activity disables the "back" button, but now my service notification can't be removed (there will eventually be conditions on when it is shown, but not right now)! I know that android manages the memory when the app is in the background like that, but if I really wanted to close that service, how would this be done?
You can use the Bindservice.The Service is stoped as the Bindservice.