Invoking services

Tutorials with advanced 'difficulty' and more Lines of Code.

Invoking services

Postby paller » Mon Jan 07, 2008 11:03 pm

See the entire text (including links, images) here.

Activity invocation is just one way of Android's service-oriented design. Android has a complete IDL-based invocation framework built into it. I was particularly curious about it because this sort of service invocation does not have to go through the service lifecycle management that slows down activity invocation considerably.

First, about services. Similarly to intents, I was a bit surprised to find out that the same Service class is used to cover two different service abstractions.

* If the service is started with Context.startService then it is a long-running background task whose lifecycle is not related to the lifecycle of the application that started it. Beside passing a start-up parameter bundle to this kind of service, Android platform does not provide any means of communicating with the service.
* If the service is started with Context.bindService then the lifecycles of the service and that of the application using it are tied. The application using the service is notified about the state of the service by means of service lifecycle events. It is also possible to communicate with this type of service using the Android IDL (AIDL) framework.

As I wanted to play with AIDL, this second type of service was of interest for me. That model reminds me of OSGi and its ServiceTracker except that OSGi was much more cumbersome to program and did not not provide any client-service separation whatsoever.

* The client requests connection to the service (by specifying an intent, as with activities). This launches the service (in separate address space)
* Once the service is ready to accept requests, the client is notified by means of a registered listener object (conforming to the ServiceConnection interface).
* The notification also carries the address of a stub object that can be used to invoke the service. If the service crashes or closes unexpectedly, the client is notified by the same service connection object.
* Meanwhile, the service can be invoked through the stub objects that the aidl tool generates from the service description.

The example code can be downloaded from here.

The service description (with the extension of .aidl) is actually quite similar to a Java file. This is the AIDL of the example program.

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. package aexp.aidl;
  3. // Adder service interface.
  4. interface IAdderService {
  5. int add( in int i1, in int i2 );
  6. }
Parsed in 0.041 seconds, using GeSHi

The convention of the aidl tool is that AIDL files are mixed with the Java files. This is how the tool finds them and converts them to Java stub files. In spite of the documentation's statement that only the Eclipse plugin converts AIDL to Java stub file, the Ant script generated by activityCreator invokes the aidl tool before compiling the Java file so if the AIDL is located correctly (in the Java source directory corresponding to the package declaration).

Although AdderService is located in the same package as the activity, it has a life (and lifecycle) of its own. The service is declared in the AndroidManifest.xml file (again, XML fragment is garbled so that the blog engine does not corrupt it).

[service class=".AdderServiceImpl"/]

The service declaration could have intent filters as activities may have. In our example we target it directly, using its class name. In order to demonstrate the service lifecycle, the lifecycle events are logged.

The client is located in a separate application. The interesting bit here is the AdderServiceConnection embedded class that acts as the service state listener. Just because the bindService call was issued, the service is not available! (actually, we can't obtain the stub object until the ServiceConnection object is notified by its onServiceConnected method).

Here is the snippet invoking the service.

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.         private void invokeService( int i1, int i2 ) {
  2.                 TextView t = (TextView)findViewById(;
  3.                 if( service == null )
  4.                         t.setText( "Service not available" );
  5.                 else {
  6.                         try {
  7.                                 int result = service.add( i1,i2 );
  8.                                 t.setText( Integer.toString( result ) );
  9.                         } catch( DeadObjectException ex ) {
  10.                                 t.setText( "Service invocation error" );
  11.                         }
  12.                 }
  13.         }
Parsed in 0.032 seconds, using GeSHi

The code invoking the service needs to be prepared for the following exceptional cases:

* Service is not yet available (onServiceConnected was not yet called) or has gone (onServiceDisconnected was called).
* For some reason, the invocation was not succesful (DeadObjectException).

I expect that service invocation performance is superior to activity invocation performance but let's see that later. :)
Posts: 29
Joined: Mon Dec 31, 2007 2:33 am
Location: London


Service invocation performance

Postby paller » Wed Jan 09, 2008 10:51 pm

See the cross-linked version of the entry here.

The whole service invocation exercise would not be complete without having an estimate of the performance of a service invocation. Activity invocation turned to be rather slow, due to the complex activity lifecycle transitions the invocation involves. Now those transitions would not occur when invoking services so I expected improvements here.

The measurement client can be downloaded from here. Note that this is just the client therefore the service application from the Invoking services post material also needs to be installed. Don't forget to update the sdk-folder and android-tools properties in the Ant build files. The client and the service applications need to be installed separately with adb install as described at an earlier post.

There are no surprises in the performance measurement client. As there are no lifecycle transitions in the client, the measurement could be performed in a simple for cycle. The average invocation time turned to be around 4 msec which is about 5-10 times faster than the activity invocation performance but is still something like 1000 times slower than a simple in-process Java call.
Posts: 29
Joined: Mon Dec 31, 2007 2:33 am
Location: London

Postby Tracy Xiang » Sat Feb 02, 2008 11:31 am

paller.I've read some of your totorials about "service",and they are great! But I am so sorry that I could not download your code ,would you please email me one. My
Best regards,
Tracy xiang
No pains,no gains.
Tracy Xiang
Posts: 3
Joined: Fri Dec 28, 2007 5:37 pm
Location: China

What can and can't be done in Services

Postby woodm » Tue Jul 22, 2008 11:37 am


Basically, I have the set of locations stored in a database and I want proximity alerts to be fired when the user is close to them. I currently have code that works and fires proximity alerts correctly when within the application. However, I want these alerts to be fired when the phone starts -- regardless of whether the application is running or not...hence the need for a service.

I just wanted to know, from someone who has had experience with services, whether such functionality is possible. The service would need to query the database for the locations, add proximity alerts and then listen for them and display notifications when an alert is raised.

Is such a thing possible with services -- so far all of the examples I have seen have been quite basic? Alternatively, could anyone think of any better suggestions on how I might implement the required functionality without services?

Thanks in advance.
Posts: 2
Joined: Mon Jul 14, 2008 5:06 pm


Return to Advanced Tutorials

Who is online

Users browsing this forum: No registered users and 4 guests