Android App Development: Android Services

By
On June 29, 2011

Android Service is used for long-running processes that do not require user interaction, such as calling a web service and parsing response. Or processes that need to be running even if the application that started the service is not on the foreground such as playing mp3 files in a music player.

we need to distinguish between A Service and a Thread or an AsyncTask: Threads or Async task perform their tasks in a background thread thus they do not block the main thread, while a service performs it’s work in the main thread. so if a service is performing an intensive task such as calling a web service, it may block the main thread until it finishes. So for intensive tasks a service should run it’s work in a background thread.

A service runs in the same process of the application and keeps running until stopped by itself, stopped by the user or killed by the system if it needs memory.

Creating a service:

to create a service we create a class that extends android.app.Service and it would be like this:

public class DemoService extends Service {

	@Override
	public IBinder onBind(Intent arg0) {
		// TODO Auto-generated method stub
		return null;
	}

}

next we need to define our service in our AndroidManifest.xml file:

<service android:name="DemoService"></service>

The service life cycle has the following events

  • onCreate(): called when the service is created.
  • onStart(): Called when the service starts by a call to startService(Intent intent).
  • onDestroy(): Called as the service is terminates.

Calling a service:

A service can be called from an activity in two ways:

  1. By calling startService(Intent intent).
  2. By binding to the service through an Binder object.

calling startService(Intent intent):

to start a service from an activity using this method, we create an intent and start the service like this:

Intent intent=new Intent(this,DemoService.class);
startService(intent);

the startService(intent) method causes the onStart() method of the service to be called, so the service can execute it’s work like this:

public class DemoService extends Service {

	@Override
	public IBinder onBind(Intent arg0) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void onStart(Intent intent, int startId) {
		super.onStart(intent, startId);
		doSomething();
	}

	public void doSomething(){
		// do some work
	}

}

the service will keep running until it stops itself via stop stopSelf() after finishing work:

@Override
	public void onStart(Intent intent, int startId) {
		super.onStart(intent, startId);
		doSomething();
		stopSelf();
	}

or it can be stopped from the activity via stopService(Intent intent).

Binding to a service through an Binder object:

As the service runs in the same process of the application the service has only one instance (singleton) instance running. you may want to keep reference to this instance to perform periodical tasks or to call the service methods themselves.

to make the service bind-able we extends Binder class and return an instance of it in the service’s onBind(Intent intent) method:

public class DemoService extends Service {

	private final IBinder binder = new LocalBinder();
	@Override
	public IBinder onBind(Intent arg0) {
		return binder;
	}

	public class LocalBinder extends Binder {
		DemoService getService() {
            return DemoService.this;
        }
    }

	@Override
	public void onStart(Intent intent, int startId) {
		super.onStart(intent, startId);
		doSomething();
		stopSelf();
	}

	public void doSomething(){
		// do something
	}

}

then we bind the service from our activity by first creating a ServiceConnection object to handle the service connection/disconnection then binding to the service by an intent like this:

public class MainActivity extends Activity {

	DemoService mService;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    ServiceConnection serviceConn=new ServiceConnection() {

                /**
                * service unbound, release from memory
                **/
		@Override
		public void onServiceDisconnected(ComponentName name) {
			mService=null;
		}

                /**
                * service is bound, start it's work
                **/
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			mService=((LocalBinder)service).getService();
			mService.doSomething();

		}
	};

    @Override
    protected void onResume() {
    	super.onResume();
        // bind to the service by an intent
    	Intent intent=new Intent(this,DemoService.class);
        // AUTO CREATE: creates the service and gives it an importance so that it won't be killed
        // unless any process bound to it (our activity in this case) is killed to
    	bindService(intent, serviceConn, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onDestroy() {
    	super.onDestroy();
        / unbind the service whena ctivity is destroyed
    	unbindService(serviceConn);
    }
}

notice that we unbind the service in the activity’s onDestroy() method to disconnect from the service and stop it from executing any further

and that’s was all about Android services, stay tuned for another Android tutorial.