DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
  1. DZone
  2. Testing, Deployment, and Maintenance
  3. Deployment
  4. Android Interface Definition Language (AIDL) and Remote Service

Android Interface Definition Language (AIDL) and Remote Service

Tony Siciliani user avatar by
Tony Siciliani
·
Feb. 08, 12 · Interview
Like (2)
Save
Tweet
Share
32.58K Views

Join the DZone community and get the full member experience.

Join For Free
In a previous article, we looked at Android Inter Process Communication (IPC) and introduced containers for fast IPC called Parcels.

We also mentioned that, for security reasons, each Android application runs in its own process, and cannot normally access the data of another application running in a different process. So mechanisms to cross process boundaries have to go through well-defined channels. To allow one application to communicate with another running in a different process, Android provides an implementation of IPC through the Android Interface Definition Language (AIDL).

The actual AIDL mechanism should be a familiar one to Java developers: you provide an interface, and a tool (the aidl tool) will generate the necessary plumbing in order for other applications (clients) to communicate with your application (service) across process boundaries. Time for some concrete example.

Say we want to implement a phone book service so that other Android applications can do a look up by name and get a list of corresponding phone numbers. We start by creating a simple Interface to express that capability, by writing a IPhoneBookService.aidl file in our source directory:

 

package com.ts.phonebook.service;

/* PhoneBook remote service, provides a list of matching phone numbers given a person's name*/
interface IPhoneBookService{

   List<String> lookUpPhone(String name);
}

As we save this .aidl file in our Android project in Eclipse, Android's aidl tool automatically generates a corresponding IPhoneBookService.java stub file in the "gen" directory of our project.  The next step is for us to actually implement our service, and we'll create a concrete PhoneBookService class. Here's the skeleton code:

 

package com.ts.phonebook.service;

import java.util.ArrayList;
import java.util.List;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;

public class PhoneBookService extends Service{

	@Override
	public IBinder onBind(Intent intent) {
		return new IPhoneBookService.Stub() { //helper method generated by Android
		          public List<String> lookUp(String name) throws RemoteException {  // our service implementation
		        	  List<String> phoneList = new ArrayList<String>();
		        	 // populate list above by looking up by name in our phone book database
                                 //... code here

		        	 // return list of phone numbers corresponding to name parameter
		                 return phoneList;
		          }
		  };
	}

}

What we did was:

  1. Make our service extend Service and implement its onBind method, which will be called once clients send requests (i.e. bind to our service). We are using a Bound Service, which means that our phone book service will not run indefinitely in the background, but come alive and remain active only for the time needed to service client requests.
  2. The onBind method returns an IBinder, which represents our service's remote implementation. We saw earlier that Android generated  a gen/IPhoneBookService.java stub file, so what we are doing is using that generated helper method to return a concrete stub to the client that contains our service method implementation.

Our client applications can now call our lookUp method to get a list of 0, 1, or more phone numbers in our database matching the name they supplied. We have implemented our service, but we still need to register it in the AndroidManifest.xml  file of our application:

 

<application...>
   ...
   <service android:name=".PhoneBookService">
         <intent-filter>
            <action android:name="com.ts.phonebook.service.IPhoneBookService" />
        </intent-filter>
   </service>
  ...
</application>
Here we are providing the intent-filter to which our service will respond. Our phone book service is now ready. Some questions the reader may have at this point:
  1. The previous article mentioned Parcels for IPC. Where exactly does that fit in here? Where are those Parcelable objects?
  2. Do I have to use AIDL for IPC, or are there any other alternative(s)?

Here, our very basic remote service simply returns a List of String objects. String types are supported out-of-the-box by AIDL , and a List of supported elements is also supported. But suppose we want to implement a more complex remote service, one that not only returns phone numbers, but  a whole set of user data, like age, occupation, sex, salary etc... If we  want to return a custom User object with all those attributes to our callers, our User class will need to be Parcelable. 

So we would write a User class implementing the Parcelable interface the same way we did in the previous article:

 

package com.ts.userdata.service;

import android.os.Parcel;
import android.os.Parcelable;

public class User implements Parcelable {
// code here @see previous article
}

And also write a user.aidl file containing just two lines:

 

package com.ts.userdata.service;

parcelable User;

Why a second .adl file? The AIDL contract requires that we create a separate .aidl file for each class declared as Parcelable that we wish to use in our service .

That's it.  We declared User as Parcelable, and implemented it as such so it can be marshaled/unmarshaled across process boundaries. This is what our service AIDL interface in IUserDataService.aidl will look like:

package com.ts.userdata.service;

import com.ts.userdata.service.User; // needed here

/* User data remote service, provides all available info about an individual given its id number */
interface IUserDataService{

   User lookUpUser(long userid);
}

The actual implementation will again use the generated Stub() but return a User type instead of a List of String types. Note the import statement. In the IUserDataService.aidl  file, we still need to import our User.aidl definition file even when it's in the same package.

As for the second question, the answer is yes, we can do IPC without AIDL, using a Messenger. In that case,  the client will not call methods on the service, but instead send messages to it.

We will explore the Messenger alternative in an upcoming article. We also haven't talked about the client side yet, i.e. create a client in a different application (in a separate Android project) that will communicate with our remote service.

From Tony's Blog

Android (robot) Interface (computing) remote application

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • DevOps for Developers — Introduction and Version Control
  • Simulating and Troubleshooting BLOCKED Threads in Kotlin [Video]
  • How To Select Multiple Checkboxes in Selenium WebDriver Using Java
  • All the Cloud’s a Stage and All the WebAssembly Modules Merely Actors

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: