30

I'm new to this android. i'm using a service to do some background work. so i'm starting the service from my activity as following.

        getApplicationContext().bindService(
        new Intent(getApplicationContext(), MyAndroidUpnpServiceImpl.class),
        serviceConnection,
        Context.BIND_AUTO_CREATE
    );

but the problem is android activity is blocked. untill the service,

         onServiceConnected(ComponentName className, IBinder service){ ..}

is called back.so i searched regarding this. i came to know that i have to start my service in new Thread. so please any one help me in doing this.

bHaRaTh
  • 3,464
  • 4
  • 34
  • 32

5 Answers5

38

To create and start a new thread, from inside an activity, you can say:

Thread t = new Thread(){
public void run(){
getApplicationContext().bindService(
        new Intent(getApplicationContext(), MyAndroidUpnpServiceImpl.class),
        serviceConnection,
        Context.BIND_AUTO_CREATE
    );
}
};
t.start();

Also, cache the value returned by bindservice, if any, if you require it for later use.

Samuh
  • 36,316
  • 26
  • 109
  • 116
  • 2
    hi Samuh its working. now it is not blocking my activity untill the service is started.. thank u very much for ur help..and i have one more question. i will place in next comment.. – bHaRaTh Feb 28 '11 at 05:30
  • once we bind the service from first activity and we make use of that service we will unbind it. so suppose in my next activity if we want to use the same service, whether we have to bind it again there right,or whether im wrong in the process. – bHaRaTh Feb 28 '11 at 05:34
  • you can bind to the same service from the other activity just like you did here. – Samuh Feb 28 '11 at 06:17
  • I think @Maurice Gavin is better - the right way to go is to off-load the processing to a worker queue - which IntentService implements. (it will process the request each at a time and the right order using a thread from the thread pool). – benchuk Oct 13 '15 at 15:39
  • Hi, What happens with the Thread when the Service is destroyed? Do I need to somehow stop the thread? – Igor Fridman Jul 31 '18 at 07:39
16

Any solution which uses Threads, Runnables, AsyncTask or otherwise with a Service will have a common problem.

The Service will block the calling Activity until after the service is started. And thus doesn't effectively thread the Service in certain cases.

The solution to this is to use the IntentService subclass.

Example of how to implement:

public class MyCustomService extends IntentService 
{   
    private DatabaseAdapter mAdapter;

    public MyCustomService() {
        super("MyCustomService");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) 
    {
        super.onStartCommand(intent, flags, startId);
        Toast.makeText(this, "MyCustomService Started", Toast.LENGTH_LONG).show();

        // Don't let this service restart automatically if it has been stopped by the OS.
        return START_NOT_STICKY;
    }

    @Override
    protected void onHandleIntent(Intent intent) 
    {
        Toast.makeText(this, "MyCustomService Handling Intent", Toast.LENGTH_LONG).show();
        // INSERT THE WORK TO BE DONE HERE
    }
}

onCreate() and onDestroy can also be overriden so long as super.onWhatever() is called inside them.

Maurice Gavin
  • 2,047
  • 1
  • 20
  • 26
3

Old question, but I'm responding because someone drew my attention to it in another question.

The OP's problem was evidently caused by the service's onBind(...) taking a long time and blocking the main thread. The correct solution is don't do that. The service needs to be redesigned so that onBind(...) returns quickly. Like almost everything else in the Android API, you should always call bindService(...) in the main thread.

The reason is that thread safety in Java is not just a matter of atomicity, but also visibility. (Scroll down to the visibility section.) In general, you should always assume that every Java API is not thread safe unless it's explicitly documented otherwise.

Kevin Krumwiede
  • 9,868
  • 4
  • 34
  • 82
2

I would recommend using an IntentService, because an IntentService by default runs on a separate thread. But still if your service class extends Service then use this code:

Thread thread = new Thread() {
    @Override
    public void run() {
        startService(new Intent(getApplicationContext(), YourService.class));
    }
};
thread.start();
Ashwin
  • 7,277
  • 1
  • 48
  • 70
1

if anyone reading this is looking for a solution involving keeping the UI thread in a fluent run, you better check out the AsyncTask task here. cheers.

gor
  • 1,046
  • 1
  • 14
  • 28
  • 5
    AsyncTask will not be useful when you have code to run without launching an application. – Erol Jul 03 '12 at 23:17
  • I`m talking about the keeping the UI thread free, i dont see the connection to what you have said... btw, a service is a part of the application, thay all run under the same process. maybe you meant running code outside the activity? – gor Mar 08 '15 at 12:41