Starting services

Sometimes, we have to execute a task that must continue to run even if the user switches to another app or activity.

How to do it...

To be able to execute a task, even if the user switches away, we use a Service instance:

  1. First, we need an instance of Service, and in most cases, we can use an IntentService instance:
    [Service]
    public class XamarinService : IntentService {
      protected override void OnHandleIntent(Intent intent) {
        // some long-running task
      }
    }
  2. In order to begin execution, we invoke the StartService() method on the Context type:
    StartService(new Intent(this, typeof(XamarinService)));
  3. We can pass data to the service when we start it by adding data to the intent:
    var intent = new Intent(this, typeof(XamarinService));
    intent.PutExtra("MyKey", "MyValue");
    StartService(intent);
  4. Additionally, in the service, we can retrieve the values from the intent's extras:
    string value = null;
    if (intent.HasExtra("MyKey"))
      value = intent.GetStringExtra("MyKey");

How it works...

Some tasks take fairly long to execute or may be a continuous execution. If normal threads are used, they are not terminated and will be leaked if the activity is killed or paused.

Note

Running threads are not automatically terminated and will leak when the activity is killed.

Services are used as they are independent of other app components and have their own lifecycle. They can be used to perform tasks and the various activities can interact with them. Services stop automatically when they complete the task, or they can be stopped by another component.

Some of the most common tasks performed by services are network or I/O operations. By delegating downloads or file processing to a background service, the user and the app are free to continue working. When the task has completed, the service can inform the user, who can then decide to continue the last task.

Another task can be to play music. The service can be started with a playlist and then left to go on ahead. When the user wants to control playback, messages can be sent to the service. This frees up the app for navigation and filtering, without having to worry about playing audio. The same goes for the service, which now no longer has to worry about any UI operations and can focus on its task.

Services inherit from the Service type either directly or indirectly. For most simple cases of executing a task in the background, we can use the IntentService instance. This type of service starts from an Intent instance and runs the task in a new thread in the background. As soon as the task is complete, the service is terminated.

This type of service is the best option if we don't need the service to handle multiple requests simultaneously. If multiple requests come in, they are queued up and executed one at a time. If the service is required to be able to handle simultaneous requests, we should inherit from the base Service type.

Note

The IntentService instance processes requests sequentially, unlike the base Service type, which processes requests simultaneously.

All services must include the [Service] attribute as this declares the service with the AndroidManifest.xml file. This is then registered by the Android OS so that we can start the services using the StartService() method or the BindService() method. If we want to prevent the service from being accessed by other apps, we can explicitly set the Exported attribute property to false.

We override the OnHandleIntent() method to perform the task. This happens on a new thread so we don't have to start our own. As soon as the task has completed and we exit the method, the service is terminated. If there are other requests in the queue, the process is repeated.

To start a service, we need to invoke the StartService() method on the Context type, such as the Activity or BroadcastReceiver instances. We pass an Intent instance that defines the service to start as well as any extra pieces of data we wish to pass to the service. Data is passed via the extras mechanism of the Intent instance through the PutExtra() method on the intent itself. In the service, we can extract the extra data from the intent using the various GetXxxExtra() methods.

Tip

Data can be passed to the service through the extras on the intent when starting the service.

There's more...

The IntentService instance does not process start requests simultaneously, but rather queues them and executes them one at a time. To handle simultaneous execution, we need to use the base Service type.

See also

  • The Stopping services recipe
  • The Handling simultaneous service requests recipe
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset