Implementing a started service

In this recipe, we will create and explain all the necessary code to implement a started service. A started service is a service that performs heavy tasks in the background and doesn't offer the possibility to communicate with it through an interface.

Getting ready

Create a new solution named Services and open it.

How to do it...

We will now see how to implement a service:

  1. Create a new C# class named MyService.cs.
  2. Add using Android.App, using Android.Util, and using System.Threading at the beginning of the class.
  3. Specify that your class extends the Service class, and use the Service attribute, shown as follows:
    using System;
    using Android.App;
    using Android.Util;
    using System.Threading;
    
    namespace Services {
      [Service]
      public class MyService : Service {
    
      }
    }
  4. Create a method named HeavyBackgroundWork() that starts a new thread. This thread will sleep for 1 second and then log into the Heavy work completed option in the console to stop the service using the StopSelf() method, shown as follows:
    private void HeavyBackgroundWork() {
      var heavyWorkThread = new Thread(()=> {
    
        Thread.Sleep (1000);
        //Sleeps for 1 s
        Log.Debug ("MyService","Heavy work completed");
        StopSelf ();
        //Stop (and destroy) the service
      });
    
      heavyWorkThread.Start();//Start the thread
    }
  5. Override the OnStartCommand() method and make a call to the HeavyBackgroundWork() method. Also, the StartCommandResult instance must return a StartCommandResult object, shown as follows:
    public override StartCommandResult OnStartCommand(Android.Content.Intentintent,StartCommandFlagsflags,intstartId) {
      HeavyBackgroundWork();
      return StartCommandResult.Sticky;
      //Determines how the service should be restarted
    }
  6. In the MainActivity class of the application, created by Xamarin Studio at the same time as the project, add a call to the StartService() method in the OnCreate() method:
    namespace Services {
      [Activity (Label = "Services", MainLauncher = true)]
      public class MainActivity : Activity {
        protected override void OnCreate (Bundlebundle) {
          base.OnCreate (bundle);
    
          SetContentView (Resource.Layout.Main);
    
          StartService (new Intent (this, typeof(MyService)));
        }
      }
    }
  7. Run the application, and the [MyService] Heavy work completed line will appear in your console. This means that the service has been successfully started, and the thread created in the HeavyBackgroundWork has waited for 1 second to destroy itself.

How it works...

In the previous section, we saw a lot of new instructions and concepts. We will now explain them in depth one by one. First of all, we have the [Service] annotation that we have placed before the declaration of our MyService class. Second, MyService extends Service class. This will create an entry in the AndroidManifest.xml file in the same way as [Activity]for activities. We can avoid this, and write the following directly in the XML file:

<service android:name="services.MyService"></service>

The next element that deserves an explanation is the following line, which we have added as the return statement of the overridden OnStartCommand() method:

returnStartCommandResult.Sticky;
//Determineshowtheserviceshouldberestarted

From the introduction of this chapter, we know that the OnStartCommand()method will return a StartCommandResult object, which specifies how the service should be restarted, in case it was destroyed by the OS in an attempt to free some memory. From the code, we can deduce that the StartCommandResult object is an enumerator, but we don't know what the Sticky option refers to. The Sticky option is one of the three different behaviors that we can give to the service in case of a restart. The possible values for the StartCommandResult object are:

  • Sticky: A sticky service will be restarted, and a null intent will be delivered to the OnStartCommand()method at the restart. This is used when the service continuously performs a long-running operation, such as updating a stock feed.
  • RedeliverIntent: This service is restarted, and the last intent that was delivered to the OnStartCommand()method before the service was stopped gets redelivered. This is used to continue a long-running command, such as the completion of a large file upload.
  • NotSticky: The service is not automatically restarted. StickyCompatibility—restart will behave as a Sticky on an API of level 5 or greater, but will downgrade to prelevel 5 behavior on earlier versions.

There's more...

According to the Android documentation (http://developer.android.com/reference/android/content/IntentFilter.html), intent filters are structured descriptions of intent values to be matched. An intent filter can match against actions, categories, and data (either via its type, scheme, and/or path) in an intent. It also includes a "priority" value that is used to order multiple matching filters. In other words, we can define a string representing an intent and associate it with a class. The string is extra data for the intent that helps Android figure out what service to start. With the service that we created earlier, it will look like the following:

[Service]
[IntentFilter(newString[]{"ca.services.MyService"})]
publicclassMyService : Service

Then, we can refer to the ca.services.MyService argument to create MyService, shown as follows:

Intent MyIntent = new Intent ("ca.services.MyService");

StartService (MyIntent);
StopService (MyIntent);

Instead of:

StartService (new Intent (this, typeof(MyService)));

See also

See also the next recipe to see how to create services that offer a way to communicate to services.

..................Content has been hidden....................

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