Intent Services in Xamarin.Android
Both started and bound services run on the main thread, which means that to keep performance smooth, a service needs to perform the work asynchronously. One of the simplest ways to address this concern is with a worker queue processor pattern, where the work to be done is placed in a queue that is serviced by a single thread.
The IntentService
is a subclass of the Service
class that provides an Android specific implementation of this pattern. It will manage queueing work, starting up a worker thread to service the queue, and pulling requests off the queue to be run on the worker thread. An IntentService
will quietly stop itself and remove the worker thread when there is no more work in the queue.
Work is submitted to the queue by creating an Intent
and then passing that Intent
to the StartService
method.
It is not possible to stop or interrupt the OnHandleIntent
method IntentService
while it is working. Because of this design, an IntentService
should be kept stateless – it should not rely on an active connection or communication from the rest of the application. An IntentService
is meant to statelessly process the work requests.
There are two requirements for subclassing IntentService
:
- The new type (created by subclassing
IntentService
) only overrides theOnHandleIntent
method. - The constructor for the new type requires a string which is used to name the worker thread that will handle the requests. The name of this worker thread is primarily used when debugging the application.
The following code shows an IntentService
implementation with the overridden OnHandleIntent
method:
[Service]
public class DemoIntentService: IntentService
{
public DemoIntentService () : base("DemoIntentService")
{
}
protected override void OnHandleIntent (Android.Content.Intent intent)
{
Console.WriteLine ("perform some long running work");
...
Console.WriteLine ("work complete");
}
}
Work is sent to an IntentService
by instantiating an Intent
and then calling the StartService
method with that Intent as a parameter. The Intent will be passed to the service as a parameter in the OnHandleIntent
method. This code snippet is an example of sending a work request to an Intent:
// This code might be called from within an Activity, for example in an event
// handler for a button click.
Intent downloadIntent = new Intent(this, typeof(DemoIntentService));
// This is just one example of passing some values to an IntentService via the Intent:
downloadIntent.PutExtra("file_to_download", "http://www.somewhere.com/file/to/download.zip");
StartService(downloadIntent);
The IntentService
can extract the values from the Intent, as demonstrated in this code snippet:
protected override void OnHandleIntent (Android.Content.Intent intent)
{
string fileToDownload = intent.GetStringExtra("file_to_download");
Log.Debug("DemoIntentService", $"File to download: {fileToDownload}.");
}