Started Services with Xamarin.Android

Started Services Overview

Started services typically perform a unit of piece of work without providing any straight feedback or results to the client. An example of a unit of work is a service that uploads a file to a server. The client will make a request to a service to upload a file from the device to a website. The service will quietly upload the file (even if the app has no Activities in the foreground), and cease itself when the upload is finished. It is important to realize that a started service will run on the UI thread of an application. This means that if a service is to perform work that will block the UI thread, it must create and dispose of threads as necessary.

Dissimilar a spring service, there is no communication channel between a "pure" started service and its clients. This means that a started service volition implement some dissimilar lifecycle methods than a bound service. The following list highlights the common lifecycle methods in a started service:

  • OnCreate – Chosen one time when the service is commencement started. This is where initialization lawmaking should be implemented.
  • OnBind – This method must be implemented past all service classes, withal a started service does not typically have a client bound to it. Because of this, a started service simply returns null. In contrast, a hybrid service (which is the combination of a bound service and a started service) has to implement and return a Binder for the client.
  • OnStartCommand – Called for each request to start the service, either in response to a phone call to StartService or a restart by the system. This is where the service can brainstorm any long-running job. The method returns a StartCommandResult value that indicates how or if the system should handle restarting the service afterwards a shutdown due to low memory. This telephone call takes place on the main thread. This method is described in more detail below.
  • OnDestroy – This method is chosen when the Service is being destroyed. It is used to perform any last clean up required.

The important method for a started service is the OnStartCommand method. It will be invoked each time the service receives a request to do some piece of work. The following code snippet is an example of OnStartCommand:

              public override StartCommandResult OnStartCommand (Android.Content.Intent intent, StartCommandFlags flags, int startId) {     // This method executes on the main thread of the application.     Log.Debug ("DemoService", "DemoService started");     ...     return StartCommandResult.Sticky; }                          

The first parameter is an Intent object containing the meta-information about the work to perform. The 2d parameter contains a StartCommandFlags value that provides some information near the method call. This parameter has 1 of two possible values:

  • StartCommandFlag.Redelivery – This means that the Intent is a re-delivery of a previous Intent. This value is provided when the service had returned StartCommandResult.RedeliverIntent but was stopped earlier it could exist properly close down. -StartCommandFlag.Retry ‐ This value is received when a previous OnStartCommand call failed and Android is trying to start the service again with the same intent as the previous failed attempt.

Finally, the third parameter is an integer value that is unique to the application that identifies the request. It is possible that multiple callers may invoke the aforementioned service object. This value is used to acquaintance a request to stop a service with a given request to start a service. It volition exist discussed in more particular in the section Stopping the Service.

The value StartCommandResult is returned by the service every bit a proposition to Android on what to do if the service is killed due to resource constraints. In that location are three possible values for StartCommandResult:

  • StartCommandResult.NotSticky – This value tells Android that it is non necessary to restart the service that it has killed. Equally an example of this, consider a service that generates thumbnails for a gallery in an app. If the service is killed, information technology isn't crucial to recreate the thumbnail immediately – the thumbnail can be recreated the next time the app is run.
  • StartCommandResult.Sticky – This tells Android to restart the Service, but not to deliver the final Intent that started the Service. If at that place are no pending Intents to handle, and then a null will be provided for the Intent parameter. An example of this might be a music player app; the service will restart fix to play music, merely it will play the last song.
  • StartCommandResult.RedeliverIntent – This value is will tell Android to restart the service and re-deliver the concluding Intent. An example of this is a service that downloads a data file for an app. If the service is killed, the data file still needs to exist downloaded. By returning StartCommandResult.RedeliverIntent, when Android restarts the service it will also provide the Intent (which holds the URL of the file to download) to the service. This will enable the download to either restart or resume (depending on the exact implementation of the code).

There is a quaternary value for StartCommandResultStartCommandResult.ContinuationMask. This value is returned by OnStartCommand and information technology describes how Android will go along the service it has killed. This value isn't typically used to first a service.

The key lifecycle events of a started service are shown in this diagram:

A diagram showing the order in which the lifecycle methods are called

Stopping the Service

A started service volition keep running indefinitely; Android volition go on the service running every bit long as there are sufficient system resource. Either the client must stop the service, or the service may terminate itself when it is done its piece of work. There are 2 ways to stop a service:

  • Android.Content.Context.StopService() – A client (such as an Activeness) can request a service stop by calling the StopService method:

                      StopService(new Intent(this, typeof(DemoService));                                  
  • Android.App.Service.StopSelf() – A service may close itself down by invoking the StopSelf:

                      StopSelf();                                  

Using startId to Cease a Service

Multiple callers can request that a service be started. If there is an outstanding starting time request, the service tin use the startId that is passed into OnStartCommand to forbid the service from beingness stopped prematurely. The startId will correspond to the latest call to StartService, and will exist incremented each time information technology is called. Therefore, if a subsequent request to StartService has not yet resulted in a call to OnStartCommand, the service can phone call StopSelfResult, passing information technology the latest value of startId it has received (instead of simply calling StopSelf). If a call to StartService has not withal resulted in a respective call to OnStartCommand, the organisation will not stop the service, because the startId used in the StopSelf call will not represent to the latest StartService call.

  • StartedServicesDemo (sample)
  • Android.App.Service
  • Android.App.StartCommandFlags
  • Android.App.StartCommandResult
  • Android.Content.BroadcastReceiver
  • Android.Content.Intent
  • Android.Bone.Handler
  • Android.Widget.Toast
  • Status Bar Icons