Question

I think this could be a duplicate but I couldn't find anything that could answer my question. I know services work in the same thread of the app. I'd like to run few tasks from a service but in a different thread. I have few points that I have to track with the gps consecutively and every time I get to one of this point I have to do some other tasks (pretty fast ones). To do that I use a BroadcastReceiver. Everything works perfectly but now I'd like to put all of this in a different thread. How can I do that? I mean I tried it but I keep getting the error "Can't create handler inside thread that has not called Looper.prepare()". I looked up for few fix but none of them seems to fit or to be the right way of programming (few of those looked like fix up but in a pretty bad way). I'll post a bit of code so that you can integrate it with your solution. Thanks in advance for any help.

public class MyService extends Service {

    private final IBinder mBinder = new MyBinder();

        ...

    @Override
    public void onCreate() {
        ...
    }

    @Override
    public IBinder onBind(Intent arg0) {
        return mBinder;
    }

    public class MyBinder extends Binder {
        MyService getService() {
            return MyService.this;
        }
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        ....
        (my tasks)
        ....
        return(START_REDELIVER_INTENT);
    }

        ............

        (final method that calls stopSelf() after it's done)

        ............

        @Override
    public void onDestroy() {
        Log.i("onDestroy", "Service stop");
        super.onDestroy();
    }
}
Was it helpful?

Solution

You can make the service a separate process. Then it will run in its own process. To do this, just add process attribute in the Android Manifest.

    <service
        android:name="<serviceName>"
        android:process=":<processName>" />

Dont forget to add : before the processname

OTHER TIPS

Simple and best way to do this is use IntentService and base class rather Service.

public class MyService extends IntentService {

    public MyService(String name) {
        super("");
    }

    @Override
    protected void onHandleIntent(Intent intent) {

        /*
         * Do Your task here, service will automatically stop as your task
         * complete. And your task will run in worker thread rather main thread.
         * Everything will handled by IntentService.
         */
    }

}

You can find complete IntenetService Demo Here

The IntentService class provides a straightforward structure for running an operation on a single background thread. This allows it to handle long-running operations without affecting your user interface's responsiveness. Also, an IntentService isn't affected by most user interface lifecycle events, so it continues to run in circumstances that would shut down an AsyncTask

An IntentService has a few limitations:

It can't interact directly with your user interface. To put its results in the UI, you have to send them to an Activity. Work requests run sequentially. If an operation is running in an IntentService, and you send it another request, the request waits until the first operation is finished. An operation running on an IntentService can't be interrupted.

For more details and example see the doc: https://developer.android.com/training/run-background-service/create-service.html

Example src code :https://developer.android.com/shareables/training/ThreadSample.zip

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top