Android Core

Android Service Tutorial

In this post, we want to talk about Android Service. This is a key component in developing Android app. Differently from Activity, Service in Android runs in background, they don’t have an interface and have a life-cycle very different from Activities. Using Service we can implement some background operation, for example we can suppose we want to load a web page from a remote server. Using a Service we can implement multitask in Android.

Service Overview

We already know that Android Activity can be started, stopped, destroyed if the system resources become too low and maybe can be recreated, a Service are designed to have a longer life. A Service in Android can be started from an Activity, from a Broadcast receiver and other services too.

We have to notice that using Service we don’t create automatically new threads, so if we implement a simple logic inside our Service, that doesn’t require long time processing we don’t need to run it a separate thread, but if we have to implement complex logic, with long time processing, we have to take care of creating a new thread, otherwise the service runs on the main thread and it could cause ANR problem.

In Android a Service is used for two main reason:

  • Implement multi-task
  • Enable Inter-Process-Communication (IPC)

A typical example of the first case is an app that required to download data from a remote server, in this case we can have Activity that interacts with a user and starts a service that accomplishes the work in background while the user can use the app and maybe when the service finishes sends a message to the user.

In the second case, we want to “share” some common functions so that different app can re-use them. For example, we can suppose we have a service that sends an email and we want to share this service among several apps so that we don’t have to rewrite the same code. In this case we can use IPC so that the service exposes a “remote” interface that can be called by other app.

In this post, we cover the first case, in this case we have a local service, local means that the service can be seen just inside our apk.

Service basic

Now we know more about Service, we want to create it. In Android to create a Service we have to extend Service class.

public class TestService extends Service {

    @Override
    public IBinder onBind(Intent arg0) {        
        return null;
    }

}

As we can see, we have to implement only one method called onBind. In our case, we are using local service, so this method should return null. As we mentioned before, a Service has its lifecycle and we can override some callback methods so that we can handle its different states:

public class TestService extends Service {

    @Override
    public void onCreate() {        
        super.onCreate();
    }

    @Override
    public void onDestroy() {        
        super.onDestroy();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {        
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public IBinder onBind(Intent arg0) {        
        return null;
    }

}

The first method onCreate is called only one time when the Service has to created. If the Service is already running this method won’t be called. We don’t call it directly but it is the OS that calls it.

OnStartCommand is the most important method because it is called when we required to start the Service. In this method we have the Intent passed at time we run the Service, in this way we can exchange some information with the Service. In this method, we implement our logic that can be execute directly inside this method if it isn’t time expensive otherwise we can create a thread. As you can see this method requires we return an Integer as result. This integer represents how the Service should be handled by the OS:

  • START_STICKY : Using this return value, if the OS kills our Service it will recreate it but the Intent that was sent to the Service isn’t redelivered. In this way the Service is always running
  • START_NOT_STICKY: If the SO kills the Service it won’t recreate it until the client calls explicitly onStart command
  •  START_REDELIVER_INTENT: It is similar to the START_STICKY and in this case the Intent will be redelivered to the service.

OnDestroy is the method called by the OS when the Service will be destroyed.

Once we have our service class, we have to declare it in the Manifest.xml so that we can use it:

<service android:name=".TestService" 
         android:enabled="true"/>

Start and Stop Service

As we know a Service has to be started and eventually stopped so that it can accomplish its task. We can suppose to start it from an activity and we could pass to the service some information using Intent. We can suppose that our Activity has two buttons one to start and one to stop the Service:

btnStart.setOnClickListener(new View.OnClickListener() {

    @Override
    public void onClick(View v) {
        Intent i = new Intent(MainActivity.this, TestService.class);
        i.putExtra("name", "SurvivingwithAndroid");        
        MainActivity.this.startService(i);        
    }
});

btnStop.setOnClickListener(new View.OnClickListener() {

    @Override
    public void onClick(View v) {
        Intent i = new Intent(MainActivity.this, TestService.class);
        MainActivity.this.stopService(i);
    }
});

In the code above at line 5, we create an Intent passing the class name that handles our Service, moreover we set some params like name and then we start the Service at line 7. In the same way, at line 17 we stop the service.

android_service[4]

Clicking on Start button we get in the Log:

android_service_start_log[5]

We can notice that the onCreate method is called because it is the first time we start the service, if we click again on start button the OS doesn’t call onCreate method. When we click on stop button the OS destroy the service.

IntentService

As we mentioned before a service runs on the main thread, so we have to be very careful when we implement some logic in this service. We have to consider that if this logic is a blocking operation or it requires long time to finish a ANR problem could occur. In this case we have to move our logic to a separate thread, meaning we have to create a thread in onStartCommand method and run it.

There is another class called IntentService derived from Service that simplify our life. This class is useful when we don’t need to handle multiple requests at the same time. This class creates a worker thread to handle different requests. This class performs this operation:

  • create a separate thread to handle the request
  • create a request queue and pass one Intent at time
  • create a default implementation of onStartCommand
  • stop the service when all the requests are processed

If we want to create a IntentService we have to extend IntentService class instead of Service:

public class TestIntentService extends IntentService {

    public TestIntentService() {
        super("TestIntentService");        
    }

    @Override
    protected void onHandleIntent(Intent intent) {

    }

}

In this case we have only one method to implement called onHandleIntent. Here we implement out logic without caring if this is operation requires long time or not, because this method is called in a separate thread.

Starting service automatically

Many times we want to start our service automatically, for example at boot time. We know to start a Service we need a component to start it. How can we do it? Well, we could use a Broadcast receiver that starts our service. If for example we want to start it at the smartphone boot time, we create first a Broadcast receiver that listens to this event and then it starts the service.

public class BootBroadcast extends BroadcastReceiver {

    @Override
    public void onReceive(Context ctx, Intent intent) {        
        ctx.startService(new Intent(ctx, TestService.class));

    }

}

and in the Manifest.xml

<receiver android:name=".BootBroadcast">    
    <intent-filter >
        <action android:name="android.intent.action.BOOT_COMPLETED"/>                
    </intent-filter>
</receiver>

 

Reference: Android Service Tutorial from our JCG partner Francesco Azzola at the Surviving w/ Android blog.

Francesco Azzola

He's a senior software engineer with more than 15 yrs old experience in JEE architecture. He's SCEA certified (Sun Certified Enterprise Architect), SCWCD, SCJP. He is an android enthusiast and he has worked for long time in the mobile development field.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

10 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
kamran
kamran
10 years ago

good tutorial just one question how to pass information to intentservice i want to set the photos of a folder as background for time intervals my problem is i do it good but after 2 times one the wallpaper travers all the photos the wallpaper doesnt change and i am using simple service

Francesco Azzola
10 years ago
Reply to  kamran

In my opinion you should use Wallpaperservice to set the wallpaper in backgroud and change it maybe using an AlarmManager to schedule it at some time.

Kirito
Kirito
10 years ago

How can I know that the service is still running.. like i to show Log.i(” Service”, “Running”); repeatedly until the service is stopped? Where should I put that Log.i??

Babar Shahzaad
Babar Shahzaad
10 years ago

I have made an application using GPS and Google Map that receive updates at regular intervals
now i want to implement background services to run application in background
what steps should i follow?

Jim Czekaj
Jim Czekaj
9 years ago

You show the onStartCommand method has having a return of:
return super.onStartCommand(intent, flags, startId);

Then you give a description of the possible return values:
START_STICKY, START_NOT_STICKY and START_REDELIVER_INTENT.

However you do not explain why the return in your example was return super.onStartCommand(intent, flags, startId);

The only place I could find this specified on the Android developer website was with respect to IntentService. You were showing when using Service. (You did briefly cover InentService later.)

Could you please explain whey you used the “return super.onStartCommand(intent, flags, startId);” for the Service?

twayta
twayta
9 years ago

how to create this class service because the default class is MainActivity that extends activity , how i can change it please ?

captain
captain
9 years ago
Reply to  twayta

You need to create a new class.

captain
captain
9 years ago

thumbs up

Waheed Akhtar
4 years ago

Service is a bit complex concept but Francesco has explained it very well. I am an old user of JavaCodegeeks. Best Android learning platform for me.

Waheed Akhtar
4 years ago

Please write some articles about android notification. How to directly reply the notification

Back to top button