I created a service (service B) from Activity (Activity A). And from service B, i created another service (service C). previously the service C used to be a thread not a service. Since it has problems in the long run i changed it to a service. The service C runs a while loop with 3 second Thread.sleep calls. But general condition it do not stop. The Log shows the service is running. But the UI is blocked and after few mins system ask me whether to shut down.
How to make this service non blocking call?
From the service documentation in Android
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).
The best way in this case is to start a new thread and then call a service from there.
Yes, from the documentation, it's clear that services are not separate processes.
Instead, please follow below to make it work:
Start a service from wherever you want to start
In service's class you wrote, write another private class extending thread which will make sure all your background stuff will run in a background thread which is separate from a mail process
Start a thread from onCreate method of service's class. If you start your background work in onStartCommand, you may accidentally start multiple services doing the same task.
Ex. You've given a button on your activity which will start background service. And if you happen to click it multiple times, it'll start those many number of services in background.
Thus, if you use override onCreate method from service, it will check if the service is already running or not and if it's not running, it'll start the service. Otherwise it'll skip and won't start another service.
I think that service C is running on main thread, try create another thread (new thread or asynctask)
Services always run on the main thread.
You need to spawn a background thread or repeatedly run a TimerTask etc in your Service C to avoid blocking the UI thread.
You can start your service in a separate thread like so:
Thread newThread = new Thread(){
Intent serviceIntent = new Intent(getApplicationContext(), YourService.class);
getApplicationContext().startService(serviceIntent);
};
newThread.start();
Please refer to this comment.
Related
I want to start a Service for a long running location fetching task.
I've chosen to use a foreground service for this task. I want this service to run in the background thread.
Now, after searching a bit, I have decided to start a new thread in onStart() of the Service and not the Activity itself. I don't want any memory leaks with the Thread having reference of Activity. I am fine with Activity being destroyed.
My question is, on which Thread is onStartCommand() is called? What will happen when I try to start the Service again?
I am not very experienced when it comes to threading, please point out anything I'm missing or am wrong about.
onStartCommand is always called on the main thread. If you want to run code on another thread, you must create it in your Service. Services by default do not create a Thread (exception: an IntentService will create a thread, and call onHandleIntent from that thread).
Only one instance of a Service exists at a time. Starting it again will not create a new Service object, but it will call onStartCommand again with the new intent. If you do not wish two threads to be created, you must prevent it yourself. Generally by keeping a reference to the thread and not creating it if not null.
IntentService has its own thread, starting another thread from handleIntent, the service considered live or completed service and doesn't matter another thread is active or nor?
and as soon as the IntentService completed its job ,is it possible to return to main thread and call another thread, but the start of the another thread could be from main thread not from activity, as the service could complete its job during any active activity.
IntentService has its own thread, starting another thread from
handleIntent
Don't ever do that. Once the IntentService's onHandleIntent() method returns, the service is destroyed and the process is likely to be killed as well. Android has no idea what threads you've started so for all it knows your process is idle and wasting resources.
If you need to "start" something else when the IntentService is done, use startActivity(), startService() or sendBroadcast() (whichever is appropriate). Again, Android doesn't know about your threads.
If you need procedure call semantics (e.g, start service, have it perform some task, then return control to the caller), IntentService isn't the right tool. Use a bound service (or bound AIDL service if you need to cross process boundaries).
I have encountered a problem while writing tests for my activity which made me wonder about this issue. I'm using ActivityInstrumentationTestCase2 and my activity sends intents to the service using startService when a button is clicked and it works fine. (My service is a singelton so i can know if it is running)
When in testing I'm doing the following:
assert service isn't running.
send intent to start the service (or press the button tried both)
wait for the service to start and assert it is running
sounds pretty simple but when i try to wait using Thread.sleep the service wont start, and same for when i try doing busy waiting. So i assumed it will need to finish the testMethod to start the service and i made the following design:
Thread helper;
#Override
tearDown() {
if (helper) join helper
super.tearDown
}
testMethod() {
assert stuff
send intent
start helper
finish
}
helperMethod() {
wait for service to start
assert stuff
}
this actually works, my guess is that it lets the main thread to finish the testMethod and then the intents are handled and my test finishes. This behavior seems very odd as i would expect that the service will start immediately as it is on the same thread or sleeping for enough time will let the service start. So anyone knows what are the conditions for the service to start, and when it happens?
Services are running on the main thread. So if you call Thread.sleep() your service won't start until the time is up.
From the Service document http://developer.android.com/reference/android/app/Service.html
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.
In android A service runs in the main thread of its hosting process, I want to know that if I want to create my own thread, then where to create it, Inside service class or Inside the activity form where we give call to the service ..?
thanks in advance
Generally, if you need your thread to persist after your activity is gone, then you need to run it in a service. The point of a service is to persist beyond the life of an activity.
Passing data across activities, services and threads may complicate the answer, and so you may end up running a thread in a service even if the thread does not persist after the activity, but that is a rare case.
Your activity should start your service, then start your thread inside the service. If you put your service launching code in a thread, all that would do is start the thread in the background but the service (and consequently the code you want to run in the background) would still run on the Main thread
If your aren't trying do some continuously running task, I would suggest using an IntentService. With an IntentService all most of the thread handling and the service cleanup is done for you.
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.