Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to start long running background task in android service

Having read most of the available documentation on Android services on the developer site and here in stackoverflow, I'm still confused by several aspects of running a service in a separate task. Hopefully someone can put me on the right track.

Let's say we have trival service framework such as

public class HliService extends Service {

    @Override
    public void onCreate() {
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // If we get killed, after returning from here, restart
        return START_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        // We don't provide binding, so return null
        return null;
    }

    @Override
    public void onDestroy() {
    }
}

and in the manifest, I have

<service android:name=".HliService" android:process=":HLI_Comms"/>

so that the service runs in its own thread.

The intent of the service is to provide a background task that will communicate to a device using a TCP socket and do some other stuff. At the risk of ignoring battery issues etc, basically I'd like it to run forever.

Something like

// Method that communicates using a TCP socket, and needs to send
// information back to the activity and receive messages from activity
// not shown here.
private void dummytask() {

    boolean keepGoing = true;
    while (keepGoing) {
        // do useful stuff in here
        // sets keepGoing false at some point
    }
    stopSelf();
}

What is the best way to initiate this method/task ?

I have looked at code in the developer site that uses a message handler and a looper, which I only partly understand, but it seems very complicated and perhaps more than I require?

I don't believe I can call this method from either onCreate() or onStartCommand() since then neither would complete when invoked from the system ? Should I start it with a timer or alarm?

I will need to add a message handler to communicate with the the gui activity, but since I'm starting the service in another thread (by virtue of the manifest "process" instruction), do I need to use AIDL instead?

I have also looked at using AysnchTask rather than extending Service, but it seems better suited to running a task and then terminating.

like image 790
SteveJP Avatar asked May 18 '12 00:05

SteveJP


1 Answers

so that the service run in its own thread.

That puts the service in its own process. This is generally something to be avoided, as it consumes extra RAM and CPU (for IPC). You can create a thread just by creating a Thread or any number of other means, most of which have been in Java for a decade or so.

At the risk of ignoring battery issues etc, basically I'd like it to run forever.

It is pretty much impossible for a service to run forever. Users or the OS will get rid of your service eventually.

What is the best way to initiate this method/task ?

Call dummytask() from a background thread.

do I need to use AIDL instead?

No. Your service can broadcast an Intent, or invoke a PendingIntent supplied by the activity, or send a Message via a Messenger supplied by the activity, etc. The best would be to use the LocalBroadcastManager from the Android Support package, but that will not work across process boundaries, forcing you into more expensive communications options.

like image 166
CommonsWare Avatar answered Oct 20 '22 00:10

CommonsWare