Showing posts with label Services. Show all posts
Showing posts with label Services. Show all posts

Tuesday, August 29, 2017

Android services

Android Services

What is a service?



Normally, when trying to execute an operation in Android it is, in some way, related and linked to a user interface. However, sometimes it would be better to run some long operations on the background, and just notify the user at the end. Or maybe just keep something running all the time, such as a music player. For these cases we can use a Service.


A service is a component which runs in the background without a user interface. Services will continue running even if the user changes to another application, ensuring the long operations are not interrupted by mistake.


There are many kinds of services at our disposal on android, so let’s see what are the main differences.


Services types



Started service



This is the basic type of service. It is usually used to perform a single operation, without returning a final result to the caller. It is created when “startService” is called for the first time and will be destroyed when “stopService” is executed. While “startService” can be called many times while the service is still running (and it will execute the “onStartCommand” function every time), it will not be re-created and will be destroyed when the “stopService” is ran for the first time. It does not matter how many times “startService” is called, it will end when “stopService” is executed once.


Started services can either be Sticky or not Sticky. The difference between a sticky and a not sticky service is what happens when the system kills the service. If the service is not a sticky service, it will not be recreated unless there are pending intents to be delivered. Meanwhile, a sticky service will be recreated regardless of if there are pending intents or not. In case there are none, it will be recreated with a null intent.


Not sticky services should be used when the it is possible to re-start the operation if unfinished and necessary, so the system can manage it appropriately. If it is vital that the service keeps running until stopped manually, you can use a sticky service.


There is also a started service called “redeliver intent”, which is useful when doing long operations that shouldn’t be interrupted. In this type of service, when the system kills it it will be re-created using the last intent that was delivered, and will use the pending intents subsequently. This allows for operations to be continued with the same intent instead of cancelling them altogether.


Bound service



Another type of service is the bound service. In this, instead of calling “startService”, when an activity wants to use this service it “binds” to it. The service is created when the first bind is made, and it continues running. This service can be binded to multiple times by different activities. When this service is binded to it returns an object that implements the “IBinder” interface to be used.


When the service is no longer required by an activity that is binded to it, the activity should call “unbind” to that service. After all activities which were bound to the service call “unbind” (meaning there are no more activities binded to this service), the service is destroyed.


Note: Bound Started service



It is possible to have a service that is both bound and started. This can be useful for some really specific situations but it is not commonly used and it normally leads to more confusion and problems than it is worth. Consider if this is exactly what you want before using it.


Scheduled service



A scheduled service is basically what the name suggests. It is a service that is scheduled to run at a later time. This can be done by using the JobScheduler class, and it allows you to set when to run this service, and even conditions to see if the service should be executed or not depending on status of the device when the scheduled time is reached.


Life cycle



A service follows a simple life cycle during its use. This lifecycle is used in both started services and bound services, although they have some differences in the middle. However, the general concept is the same.


First, the service is created. This is done by calling “startService” or “bindService” depending on the type of service. At this point is when it calls the “onCreate” function which can be used for initial setup on either type of service.


Immediately after creation, it starts executing the “onStartCommand” or “onBind” function (dependin on the case). Here is where the main processing of the service is executed and where it will continue until the service is stopped. In case of bound services, “onBind” will be called every time a new activity binds itself to the service, and “onUnbind” will be called when any activity unbinds itself.


When the service is stopped (either by calling “stopService” or the last “unbind”), the function “onDestroy” is called. Finall, the service is shut down and the life cycle comes to an end.


Creating a service



Now let’s see how to actually create a service. For this exampl, we will create a started service, but creating a bound service is not really that different.


To create a service you need to create a new class that extends from “Service”. This will force us to override the method “onBind”, which is for bound services. Since we will now create a simple started service, we can return null here and move on.


Now we can implement the methods we wish. As explained earlier, we can implement “onCreate”, “onStartCommand”, or “onDestroy” depending on what we need. There are others that we could implement but those are not important for this basic tutorial. The one that we should implement to actually have a started service as we want is the “onStartCommand” one. Here is also where we can choose which type of started service we want to create. This is determined by what we return at the end. Return either “START_NOT_STICKY”, “START_STICKY”, or “START_REDELIVER_INTENT”, depending on what you wish to do.


Here you can see the code for creating a started not sticky service:

package com.servicesexample.innuy.servicesexample; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.support.annotation.Nullable; import android.widget.Toast; /** * Created by Innuy. */ public class ExampleService extends Service { @Nullable @Override public IBinder onBind(Intent intent) { return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { Toast.makeText(this, "Here the service is started", Toast.LENGTH_LONG).show(); return START_NOT_STICKY; } }
What we need to do now is add our new service to the Android manifest. Just add the following line changing the name of the service to yours:


<service android:name=".ExampleService"></service>
The last step is to call this service. For this you just need to create an appropriate intent and call “startService” from an activity as it is shown in the code below:

startService(new Intent(getBaseContext(), ExampleService.class));
And there it goes! If you use the above code you will see the Toast being shown whenever you start the service. To stop this service just call “endService” with an intent of the same service.


Sources

Services Documentation - Android Developers https://developer.android.com/guide/components/services.html


Secondary links: