I'm trying to play around with an Android "Service" but the more I play with it, the more I see that it's intimately tied to the UI thread. What I mean is that I fire up an Activity, and call a Service, just for yucks do a very long for loop in the Service. I would expect that for loop to happen in the "background" and not interfere with my UI, but it's freezing my UI while the for loop is going on (and it releases my UI back to normal when the for loop is done). Why wouldn't the "Service" just run in the "background" instead of messing up my UI? How can I make it run in the "background"?
from the manual:
What is a Service?
Most confusion about the Service class actually revolves around what
it is not:
A Service is not a separate process. The Service object itself does
not imply it is running in its own process; unless otherwise
specified, it runs in the same process as the application it is part
of.
A Service is not a thread. It is not a means itself to do work off
of the main thread (to avoid Application Not Responding errors).
This is how you should do (again, taken from the manual & also mentioned by #Jave):
Note that services, like other application objects, run in the main
thread of their hosting process. This means that, if your service is
going to do any CPU intensive (such as MP3 playback) or blocking (such
as networking) operations, it should spawn its own thread in which to
do that work. More information on this can be found in Processes and Threads. The IntentService class is available as a standard
implementation of Service that has its own thread where it schedules
its work to be done.
From the documentation for Service:
Note that services, like other application objects, run in the main
thread of their hosting process. This means that, if your service is
going to do any CPU intensive (such as MP3 playback) or blocking (such
as networking) operations, it should spawn its own thread in which to
do that work. More information on this can be found in Processes and
Threads. The IntentService class is available as a standard
implementation of Service that has its own thread where it schedules
its work to be done.
class DownloadingService extends Service
{
...
#Override
public void onCreate()
{
...
// Start up the thread running the service. Note that we create a
// separate thread because the service normally runs in the process's
// main thread, which we don't want to block.
Thread notifyingThread = new Thread(null, mTask, "DownloadingService");
notifyingThread.start();
}
private Runnable mTask = new Runnable()
{
public void run()
{
// here the job is going to be done
}
};
}
Related
Can someone help me understand how to use Android Service or IntentService correctly. The documentation seems to contradict itself here:
Caution: A service runs in the same process as the application in which it is
declared and in the main thread of that application by default. If your service
performs intensive or blocking operations while the user interacts with an
activity from the same application, the service slows down activity performance.
To avoid impacting application performance, start a new thread inside the service.
and here
public class HelloIntentService extends IntentService {
/**
* A constructor is required, and must call the super IntentService(String)
* constructor with a name for the worker thread.
*/
public HelloIntentService() {
super("HelloIntentService");
}
/**
* The IntentService calls this method from the default worker thread with
* the intent that started the service. When this method returns, IntentService
* stops the service, as appropriate.
*/
#Override
protected void onHandleIntent(Intent intent) {
// Normally we would do some work here, like download a file.
// For our sample, we just sleep for 5 seconds.
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// Restore interrupt status.
Thread.currentThread().interrupt();
}
}
}
Given the whole purpose of the Service or ServiceIntent is to run long running jobs in the background without affecting the UI why then does the example code do exactly what the Caution indicated you should not do - and I am assuming a call to Thread.sleep() will cause the main thread to block.
Am I correct in the following understanding:
The service itself still runs on the main application thread but has no UI component (Activity) and will continue running even if the application is not used by the user, unlike an Activity which will not
Any long running background work must still create a separate thread to avoid blocking the main application thread
AsyncTask is associated with an Activity which presumably will stop running if the application is no longer the active application (i.e. if the user switches to another application) which is why one would use Service or ServiceIntent if the task needs to keep running.
IntentService will run the task on a separate thread to the main thread so there is no need to worry about blocking the main thread with long tasks or when calling Thread.sleep().
Have I misunderstood something with the description of Android Service or ServiceIntents?
Your first comment is from the the documentation about services in general.
There is nothing in Android named ServiceIntent. Your code snippet is an IntentService.
In Java, we have classes and inheritance. Service is the base class from which all services inherit. IntentService extends Service.
If you call startService(), pointing to a class of yours that inherits directly from Service, you need to implement a background thread yourself, as Service will not do that for you.
If, however, you call startService(), pointing to a class of yours that inherits from IntentService, then you will get a background thread created for you automatically by IntentService. This is code added by IntentService, above and beyond what Service provides.
and I am assuming a call to Thread.sleep() will cause the main thread to block.
No, because onHandleIntent() is called on the IntentService-supplied background thread.
The service itself still runs on the main application thread
No. In Java, objects do not run on threads. Methods run on threads.
Any long running background work must still create a separate thread to avoid blocking the main application thread
Any long-running background work needs to be performed on a background thread. Whether that is a thread that you create (e.g., in a direct subclass of Service) or whether it is a thread that is provided to you (e.g., in a direct subclass of IntentService) varies.
AsyncTask is associated with an Activity which presumably will stop running if the application is no longer the active application
The primary role of a service is to tell Android that we are doing background work that should continue for a while, even if the app's UI moves to the background. That is because Android will terminate your process eventually, to free up system RAM for other apps.
Using a service will tend to keep your process around for a little while longer. An AsyncTask, or a bare Thread, does not do this. When the app's UI moves to the background, your process is not terminated immediately, but it may be terminated soon, and so if you want greater assurance that your work will get done, you use a service to manage that work.
In a recent answer, I read
A service does not run on its own thread, it runs on the UI thread
I've read similar statements in many other service-related questions.
If I call startService() from an Activity, will the Service run on the Activity's UI Thread or does it spawn a new process with it's own UI Thread?
If it runs on the Activity's UI Thread, doesn't that risk making the Activity unresponsive?
Yes services does run on main thread , About ANR(application not responding ) concern , there will higher chances of ANRs if your service is doing a long processing work using CPU so the official docs also recommends to use Worker Threads for efficiency. docs
You must read the caution paragraph in the docs to confirm
If your task is one time shot then Use IntentService which implicitly use threading mechanism for processing but IntentService will destroy itself automatically when the task is done so you will have to start it again for the next time and so.
android:process : Using this to start a service in an another process will cause usage of more memory. This will cause creating two processes for your app in separate heap memory space which also require other maintenance as well.So this is rarely used and i would not recommend to use this for a regular service task.
If I call startService() from an Activity, will the Service run on
the Activity's UI Thread or does it spawn a new process with it's
own UI Thread?
If it's a Service (not an IntentService), it will run on the main Thread of your app's process, as long as you do not define it as a separate process explicitly (by adding the android:process tag in the Manifest).
If it runs on the Activity's UI Thread, doesn't that risk making the
Activity unresponsive?
Yes it does, if you perform CPU intensive/blocking operations.
To prevent that, you can either start new Thread(s) from your Service, or use an IntentService, which will automatically spawn a new worker Thread for its work.
From the Services Docs it clearly explains your answer.
Caution: A service runs in the main thread of its hosting process—the
service does not create its own thread and does not run in a separate
process (unless you specify otherwise). This means that, if your
service is going to do any CPU intensive work or blocking operations
(such as MP3 playback or networking), you should create a new thread
within the service to do that work. By using a separate thread, you
will reduce the risk of Application Not Responding (ANR) errors and
the application's main thread can remain dedicated to user interaction
with your activities.
In a recent answer, I read
A service does not run on its own thread, it runs on the UI thread
This is just plain wrong. A Service is an object (an instance of a class). It doesn't run on any thread, it doesn't run at all. It just "is". The methods of the Service may run on any thread, depending...
Specifically, the lifecycle methods of a Service (onCreate(), onStartCommand(), etc.) that are called directly from the Android framework run on the main (UI) thread, which may or may not be the same thread that called startService(). However, a Service can (and usually does) start other background threads, as many as it needs to, to perform the necessary work.
If I call startService() from an Activity, will the Service run on the
Activity's UI Thread or does it spawn a new process with it's own UI
Thread?
See above. If you want your Service to run in a separate process, you can do this by specifying android:process=":service" in the <service> declaration in the manifest. By default, services run in the same process as the other components (Activity, BroadcastReceiver, etc.) of your application.
If it runs on the Activity's UI Thread, doesn't that risk making the
Activity unresponsive?
That depends on what your Service is doing! Obviously if your Service is doing a lot of compute-intensive processing on the UI thread it will make your app unresponsive. If your Service is doing I/O on the UI thread, Android will usually throw exceptions (in more recent versions of Android). This is the reason that services usually start background threads to do work. However, if your Service is lightweight, then there is no reason why methods of your Service cannot run on the UI thread. As I said, it depends...
IntentService runs on the background thread, so, if you want to do one-off tasks then use that.
I've built a music player which is running on a Service.
I'm preforming various actions as play, pause, next song, previous song etc through a binding to the service from my activity.
It works totally fine.
So to my question:
Is it ideal to put the service on a new thread? I know Service run by default on Main/UI thread.
If not, how do I know when to actually put something on a new thread? Can I put the whole Service instance on new thread or just a part of the code in the Service?
I guess this is called a long running service, shouldnt that be on a own thread to not block the UI?
When debugging I can see this in Logcat: I/Choreographer(691): Skipped 60 frames! The application may be doing too much work on its main thread...
That got me wondering too! :o
As my title says, I'm very confused about this!
You are right, Services are not threads (they do not create a different thread).
When started form an activity they would block the main/UI thread fi running long operations.
you can use IntentService - which start their own thread to perform background long running operations - but that would probably suits a download file task or long running calculation better than playing music.
note that IntentService creates and destroys the thread by itself (when the work is done).
Another option would be to create you own thread manually.
That said, I would consider this article:
http://developer.android.com/guide/topics/media/mediaplayer.html
It talks about a service in the foreground using startForeground() which adds a notification to the status bar, letting the user be aware of the fact that the service is running - as well as promoting the service so it won't get destroyed in case of low memory conditions (it could be - but it will probably be the last one to be closed).
the example is about running media player while taking the main thread blocking into consideration as well as handling system events to pause and play music as expected (using BroadcastReceiver )
Also note this:
http://developer.android.com/guide/components/services.html
Should you use a service or a thread?
A service is simply a component that can run in the background even
when the user is not interacting with your application. Thus, you
should create a service only if that is what you need.
If you need to perform work outside your main thread, but only while
the user is interacting with your application, then you should
probably instead create a new thread and not a service. For example,
if you want to play some music, but only while your activity is
running, you might create a thread in onCreate(), start running it in
onStart(), then stop it in onStop(). Also consider using AsyncTask or
HandlerThread, instead of the traditional Thread class. See the
Processes and Threading document for more information about threads.
Remember that if you do use a service, it still runs in your
application's main thread by default, so you should still create a new
thread within the service if it performs intensive or blocking
operations.
I am looking for what service should be used in android applicaton.
Docs says
A Service is an application component that can perform long-running operations in the background and does not provide a user interface.
I have read this thread Application threads vs Service threads that saying same services are for running operation in background.
But here this can be done using Thread also. Any difference between them and where you should use them
UPDATE based on latest documentation:
Android has included in its documentation on when you should use Service vs Thread. Here is what it says:
If you need to perform work outside your main thread, but only while
the user is interacting with your application, then you should
probably instead create a new thread and not a service. For example,
if you want to play some music, but only while your activity is
running, you might create a thread in onCreate(), start running it in
onStart(), then stop it in onStop(). Also consider using AsyncTask or
HandlerThread, instead of the traditional Thread class. See the
Processes and Threading document for more information about threads.
Remember that if you do use a service, it still runs in your
application's main thread by default, so you should still create a new
thread within the service if it performs intensive or blocking
operations.
Another notable difference between these two approaches is that Thread will sleep if your device sleeps. Whereas, Service can perform operation even if the device goes to sleep. Let's take for example playing music using both approaches.
Thread Approach: the music will only play if your app is active or screen display is on.
Service Approach: the music can still play even if you minimized your app or screen is off.
Note: Starting API Level 23, you should Test your app with Doze.
Android Documentation - Services
A Service is meant to run your task independently of the Activity, it allows you to run any task in background. This run on the main UI thread so when you want to perform any network or heavy load operation then you have to use the Thread there.
Example : Suppose you want to take backup of your instant messages daily in the background then here you would use the Service.
Threads is for run your task in its own thread instead of main UI thread. You would use when you want to do some heavy network operation like sending bytes to the server continuously, and it is associated with the Android components. When your component destroy who started this then you should have stop it also.
Example : You are using the Thread in the Activity for some purpose, it is good practice to stop it when your activity destroy.
This is the principle i largely follow
Use a Thread when
app is required to be visible when the operation occurs.
background operation is relatively short running (less than a minute or two)
the activity/screen/app is highly coupled with the background operation, the user usually 'waits' for this operation to finish before doing anything else in the app.
Using a thread in these cases leads to cleaner, more readable & maintainable code. That being said its possible to use a Service( or IntentService).
Use a Service when
app could be invisible when the operation occurs (Features like Foreground service could help with operations being interrupted)
User is not required to 'wait' for the operation to finish to do other things in the app.
app is visible and the operation is independent of the app/screen context.
Reference from https://developer.android.com/guide/components/services.html
A service is simply a component that can run in the background even when the user is not interacting with your application. Thus, you should create a service only if that is what you need.
If you need to perform work outside your main thread, but only while the user is interacting with your application, then you should probably instead create a new thread and not a service.
For example, if you want to play some music, but only while your activity is running, you might create a thread in onCreate(), start running it in onStart(), then stop it in onStop().
Remember that if you do use a service, it still runs in your application's main thread by default, so you should still create a new thread within the service if it performs intensive or blocking operations.
My Approach for explanation is simple:
Create a thread when you are in the activity and want to do some background operation with frequent communication with the main thread.
Alert- Don't create too many threads as 1 thread is equal to 1 processor thread. If you want to do parallel processing with threads(multiple) try your hands on Executors
Now you want long running operations with less interaction with UI then go for Service. Keep in mind service runs on UI thread. But now you want the processing should be done in background thread, then go for Intent Service.Intent service maintains their Thread Pools and do not create new threads and runs your tasks serially.
What is the cons of using Thread instead of using Android Service in an App for long running task. What will happen if I don't use Android Service for long running task?
Service:
A service is a component which runs in the background, without direct interaction with the user. As the service has no user interface it is not bound to the lifecycle of an activity.
Services are used for repetitive and potential long running operations, like Internet downloads, checking for new data, data processing, updating content providers and the like.
It is possible to assign services the same priority as foreground activities. In this case it is required to have a visible notification active for the related service. It is frequently used for services which play videos or music.
Threads:
They are simple runnable threads. You can execute non UI stuff with these threads but you can't perform UI tasks in them (as UI is not thread safe). For dealing with UI in these threads, you will have to use Handlers, which is quite cumbersome for beginners to get a grip and understanding of them.
So depending on your needs and app you can choose the one best suits you.
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. Additionally, a component can bind to a service
to interact with it and even perform interprocess communication
(IPC). For example, a service might handle network transactions, play
music, perform file I/O, or interact with a content provider, all
from the background.
On other hand, Threads are the cornerstone of any multitasking
operating system and can be thought of as mini-processes running
within a main process, the purpose of which is to enable at least the
appearance of parallel execution paths within applications.
They are to be used as per requirement and we cannot actually point out pros and cons of either of them as both of them are essential in different situations.
What will happen if I don't use Android Service for long running task?
You might get lucky and your code finishes. Then again, you might not get lucky, and your code gets killed at a random point in time.
Aside from the textbook descriptions of what an Android Service is and what a Thread is, the main difference between the two which is directly relevant to your question is how the OS threats them.
A thread is a way to execute code in the background, while a service is a way to make Android aware you are executing code in the background.
As far as the underlying Linux kernel is concerned, it knows only about threads, and cares about them only with regards to thread switching and prioritization. Whether there is a service has no impact on this.
However, as far as the Android device memory management and task prioritization goes, Android does not know or care about threads in your process. It only knows about services, and interacts with them on the main app process thread only.
Thus, for as long as you have a thread alive, the kernel will happily try to keep the process alive and allocate CPU time for that thread execution.
However, unless you have an activity, service, content provider, or a broadcast receiver alive, the Android memory manager might decide to kill your process to reclaim its resources for another higher priority process, no matter what threads might be working at this point.
Therefore, while you could go away with running stuff on a separate thread if the user is interacting with your activity, if you want to make sure the background task finishes successfully and is not interrupted at a random point, you need to wrap it in a service (preferably one that is bound by an activity, or is elevated to UI priority by showing a notification).
Note that having a service does not guarantee you that its code will be running in the background. Android will call the lifecycle methods (onStartCommand/onBind/onCreate/OnDestroy) on the main thread of the application process. Your code will have to start a thread to ensure true background execution.
Services are highly recommended and used in Android to do both foreground and background tasks. Instead of going into the definitions I would highly recommend you to look into IntentService class specifically in Android. Available from API Level 3 this class does most of the worker thread heavy lifting for your background task. This class handles asynchronous requests expressed as Intents. Clients send request using startService(Intent) calls. The service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work. Coolest thing you can use this along with an AlarmManager implementation to do say what you want to do every 10-15 mins and still not worry about threads and handler explicit implementation as you would have to if you use Service class.
Here is a short bit of code on how to implement it.
public class UpdateService extends IntentService {
public UpdateService() {
//constructor
}
#Override
public void onCreate() {
super.onCreate();
//Called by the system when the service is first created.
}
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStart(intent, startId);
return(START_REDELIVER_INTENT); //Intent Relidelivery
//You should not override this method for your
IntentService and remember onStart() for IntentService is
deprecated.
}
#Override
protected void onHandleIntent(Intent intent) {
//do your main background tasks here forget about threading doing anything
in here Android will do the heavylifting as required
}
#Override
public void onDestroy() {
super.onDestroy();
//finalize your objects GC etc here
//Called by the system to notify a Service that it is no longer
used and is being removed.
}
}
Services are best implementations for long running tasks that you don't need user input or ui updates right away. If you absolutely don't need to don't use threads and handlers since you might come across a lot of concurrency / deadlock etc issues.
Hope this helps.
Nothing will happen, I ran an algorithm in a async task about 90 hours. Worked fine.
Async Task: seperate a "heavy" task from the UI, for example a download
Service: seperate a task from the App, for example an alarm clock