I have an application that I wants it to keep running when user puts it in the background. I was wondering what would be the difference between an application put in the background (so onPause() is called) and a Service? They seem both to be working in the background
Thanks
From the docs:
A Service is an application component that can perform long-running
operations in the background
When your Activity goes into onPause, there is no guarantee from the system that it will not be destroyed next. In your case, you aren't seeing it perhaps because you have enough memory available, but under different circumstances and on different phones, the Activity can be destroyed, even if you are doing work. Therefore you should use the service for background tasks.
You should use a Service. Even though your Activity can continue to execute code after onPause() or onStop(), you should use a service. A Service is not meant to have a UI and the system prioritizes them differently when deciding to kill components that are no longer in use if the system needs to reclaim memory.
Related
I have an activity that contains an Instance of FileObserver. I start watching in onCreate and stop watching in onDestroy of the activity. So what happens if onEvent is doing some operation and the activity is destroyed (user presses back button)? Does my onEvent continue to finish what it was doing? Basically I am wondering whether onEvent should start a service or handle its business itself.
Does my onEvent continue to finish what it was doing?
At least briefly, yes. FileObserver is not tied to a specific component's lifecycle, like that of an Activity.
However, once your app is no longer in the foreground, your process can be terminated at any point, to free up system RAM for other apps. Android is not going to pay any attention to your FileObserver and its onEvent() processing when this occurs, by default.
If you expect the work to happen quickly — say, under a second — you should be able to keep it where it is.
If, however, the sort of work that you are doing is more substantial, I would consider having a service do the work. Per our prior discussion, while the FileObserver should not be in an IntentService, the work triggered by the FileObserver could be. onEvent() would call startService() to tell the service to go do the work. Services are a signal to the OS that you are actively doing work on behalf of the user, and so your process is more likely to hang around for a bit longer.
Unless the Application is stopped the code in your onEvent will continue to run.
FileObserver.onEvent documentation
This method is invoked on a special FileObserver thread. It runs independently of any threads, so take care to use appropriate synchronization! Consider using post(Runnable) to shift event handling work to the main thread to avoid concurrency problems.
So the only think you need to be concerned with is what exactly you are doing in onEvent. For instance if you are updating UI or interacting with the Activity / Fragment in your onEvent method then this could cause a crash if the Activity goes away.
With that in mind a service will certainly increase the odds that the application does not terminate while you are performing your work.
Service documentation
The Android system will force-stop a service only when memory is low and it must recover system resources for the activity that has user focus. If the service is bound to an activity that has user focus, then it's less likely to be killed, and if the service is declared to run in the foreground (discussed later), then it will almost never be killed. Otherwise, if the service was started and is long-running, then the system will lower its position in the list of background tasks over time and the service will become highly susceptible to killing—if your service is started, then you must design it to gracefully handle restarts by the system. If the system kills your service, it restarts it as soon as resources become available again...
So the bottom line is that a service is more likely to keep your application alive. Event more likely if you call startForeground but in this case you need to be willing to show a notification to the user.
I have a long running background task that I would like to start when the app launches and shutdown when the application shuts down. I'm already quite aware of the activity life cycle and what gets called when an activity gets created and destroyed.
I'm coming from an iOS background, and over there we have some calls that are made during application startup and shutdown. Is there something similar in the android world? I've searched a lot and all I'm finding are answers relating to an activity, not the entire application.
(Android is relatively new to me, so I may just not know the correct terminology to search for.)
EDIT:
I'll try an be a bit more specific. I have a background task that needs to be continuously running while the user is using the application. It will be streaming data from a server continuously while the application is active. It does not need to run when the application is in the background. It doesn't seem to make sense to me to tie the startup / shutdown of this background process to any one single activity since it may not be the same one activity that starts up when the application becomes active.
I am (possibly mistakenly) assuming that the OS takes care of starting / stopping background threads when the application resumes and pauses. If that is, in fact, the case, then all I really need to do is spin up the background task when the application first launches, i.e. when it is loaded into memory and becomes active for the first time that session.
It doesn't seem to make sense to me to tie the startup / shutdown of this background task to any one single activity since it may not be the same one activity that starts up when the application becomes active.
That's reasonable. It is somewhat difficult to implement, though.
I am (possibly mistakenly) assuming that the OS takes care of starting / stopping background threads when the application resumes and pauses.
You have it exactly backwards. Android pays not one whit of attention to any threads that you fork yourself, directly or via thin wrappers like AsyncTask.
In addition to that point of confusion, you appear to be equating "user switching to another app" with "app shutdown". Those may be the same thing in single-tasking operating systems. They are not the same thing in Windows, OS X, Linux, Android, etc.
So, what you seem to be seeking is having a background thread running doing this streaming work while your UI is in the foreground, and then stop when your UI is in the background. The problem is that there really isn't a straightforward way of accomplishing that in Android.
One close approximation would be to create and register a custom Application class, where you override onTrimMemory(), and stop your background work when you get to TRIM_MEMORY_UI_HIDDEN, TRIM_MEMORY_BACKGROUND, TRIM_MEMORY_MODERATE, or TRIM_MEMORY_COMPLETE -- whichever of those that you encounter first. If, when one of those arrives, you determine that your streaming thread is still outstanding, shut it down.
In terms of startup, you could use onCreate() on that same Application singleton. The problem is that this will be called on any process creation, which may include scenarios in which you do not have UI (e.g., you are responding to some system broadcast, like ACTION_BOOT_COMPLETED), or possibly your process is going to parts of your UI that do not depend on the streaming. If you have none of those scenarios, then onCreate() in Application would be fine. Otherwise, kick off the streaming in onCreate() of whatever activities need it.
While normally we manage long-running threads with a Service, that is for cases where we explicitly want the thread to continue after our UI is in the background. Since you do not want that, you could skip the service.
It depends on what you want to do exactly. When you're just interested in the app starting for the first time you could #Override onCreate().
Or maybe you want to use onResume() as this will get called whenever a user brings the app to the foreground.
But this really depends on what exactly your background task is doing and what you want to do with it, to get an exact answer you need to provide more details.
Here is an overview for the actiity life cycle that should help you:
You can extend the default Application class and implement it's onCreate() method to detect when the app is launched. There is no corresponding method for when the app gets closed though.
Do not forget to specify it in the Manifest file.
In Android the application isn't shut down unless the system runs low on memory. You won't get a warning about that, it will just call your Service's onDestroy lifecycle method. If you want to do it when the Activity is visible on screen, use onStart and onStop. If you want to do it when the Activity is resident in memory, use onCreate and onDestroy.
I have an android application that binds itself to a remote service once the application starts. The remote service provides an abstraction to a bluetooth video camera so we can send commands and receive events from it easily. The binding happens from the Application itself as opposed to an Activity. It is important to me that as long as the camera connection to bluetooth is active that my application stay running so I can receive events from the remote service. The main reason is that I need to know if it's recording or not and if so I need to periodically send it GPS coordinates.
Will my application have a better chance of not being killed if I use a service within my own application to manage that? Or is my application safe from being killed since it is still bound to the remote service? Of course, I understand that the android system will kill my app if memory requirements require it to but will it ever kill my app just because it's been sitting for awhile not doing much?
The application's process should only be removed if memory is low, but you will raise the perceived importance of your process if you use a service rather than an empty process or a background activity. You can also use startForeground() to make it less likely that Android will stop your service.
From http://developer.android.com/reference/android/app/Activity.html#ProcessLifecycle:
Process Lifecycle
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. As described in Activity Lifecycle, the decision
about which process to remove is intimately tied to the state of the
user's interaction with it. In general, there are four states a
process can be in based on the activities running in it, listed here
in order of importance. The system will kill less important processes
(the last ones) before it resorts to killing more important processes
(the first ones).
The foreground activity (the activity at the top of the screen that the user is currently interacting with) is considered the most
important. Its process will only be killed as a last resort, if it
uses more memory than is available on the device. Generally at this
point the device has reached a memory paging state, so this is
required in order to keep the user interface responsive.
A visible activity (an activity that is visible to the user but not in the foreground, such as one sitting behind a foreground
dialog) is considered extremely important and will not be killed
unless that is required to keep the foreground activity running.
A background activity (an activity that is not visible to the user and has been paused) is no longer critical, so the system may
safely kill its process to reclaim memory for other foreground or
visible processes. If its process needs to be killed, when the user
navigates back to the activity (making it visible on the screen
again), its onCreate(Bundle) method will be called with the
savedInstanceState it had previously supplied in
onSaveInstanceState(Bundle) so that it can restart itself in the same
state as the user last left it.
An empty process is one hosting no activities or other application components (such as Service or BroadcastReceiver classes).
These are killed very quickly by the system as memory becomes low. For
this reason, any background operation you do outside of an activity
must be executed in the context of an activity BroadcastReceiver or
Service to ensure that the system knows it needs to keep your process
around.
Sometimes an Activity may need to do a long-running operation that
exists independently of the activity lifecycle itself. An example may
be a camera application that allows you to upload a picture to a web
site. The upload may take a long time, and the application should
allow the user to leave the application will it is executing. To
accomplish this, your Activity should start a Service in which the
upload takes place. This allows the system to properly prioritize your
process (considering it to be more important than other non-visible
applications) for the duration of the upload, independent of whether
the original activity is paused, stopped, or finished.
It seems that when I don't need interprocess communication, there's almost no reason to use a Service. The only reason I am aware of is this: if my process has a started Service, the process is less likely to be killed.
I could just have a utility class with dontWantToBeKilled() and canBeKilled() methods, which would start / stop a dummy Service. Apart from that, I won't use Services. Is this right?
Yes, there are other reasons.
Your application runs in a process which can be killed by the system whenever it needs more resources.
According to this a running service has a higher priority than an Activity that isn't in the foreground, meaning that the system is more likely to kill an application process that has an Activity in the background than one that has a Service running in the background.
The documentation for Service states that:
If the service has been started, then its hosting process is
considered to be less important than any processes that are currently
visible to the user on-screen, but more important than any process not
visible. Because only a few processes are generally visible to the
user, this means that the service should not be killed except in
extreme low memory conditions.
So, you can use Services to decrease the likelihood of your application process being killed.
Even though the Service runs in the same process as an Activity nothing guarantees you that your Activity will not be killed.
From Processes and Threads:
For example, an activity that's uploading a picture to a web site
should start a service to perform the upload so that the upload can
continue in the background even if the user leaves the activity. Using
a service guarantees that the operation will have at least "service
process" priority, regardless of what happens to the activity. This is
the same reason that broadcast receivers should employ services rather
than simply put time-consuming operations in a thread.
Conclusion:
If you want to do a background operation that will take a while and it's important it finishes correctly, use a Service.
Its not necessary that if A process started service then,Process is likely to be killed.Actually process remain alive or not it does not affect service.As its completely background procedure.May be the situation that you have started a process to just start a service.So process and service can not interrelated like that.
AFAIK i did not got your final question properly.
I am developing an application for a recognized financial institution. It is very important for them to manage security, and one of the requirements is that the application cannot run in the background. It was specifically requested that if a phone call is received, the application must get killed.
I tried using BroadcasterReceiver, by starting an activity when I hang up a call but apparently it runs as a service, and while my application is no longer running the activity is always started.
Is there any way to avoid background processing, like in iOS?
onPause() is called when your activity is going into the background.
If you overrode onPause() and stopped any sensitive activity in there, you would always catch the Activity going into the background.