
AIDL (Android Interface Definition Language) and Inter-Process Communication (IPC)
In this article, we will try to describe our experience with AIDL in Android IPC.
It contains an example application with a service that is running in a separate process.
The article should be considered as:
Service is a component of an Android application without a user interface, designed to perform resource-intensive and / or lengthy operations.
A service can be launched in a process separate from Activity.
Benefits:
Disadvantages:
In a literal translation - the language for the description of Android interfaces. Used to describe the composition and decomposition of Java objects into OS primitives for direct transfer between processes.
AIDL files are very similar to standard interfaces in java with the exception of:
Using AIDL, java code is automatically generated to generate stabs.
The application we developed is a gallery for Android that allows you to view photos from a memory card and photo-sharing networks.
The main tasks of the service in this application are: obtaining metadata (information about albums, photos, friends), monitoring their updates and everything else that is associated with them. The service constantly stores relevant information and is ready at any time to give it to the main Activity for display.
The following are key sections of code and the process of creating a primitive service is described:
The following AIDL files are used to communicate between the service and Activity:
IDataSourceService.aidl - service interface:
IDataSourceServiceListener.aidl - interface for listeners of messages from the service:
Data is transmitted using two classes that implement the Parcelable interface - Album and Photo. The declaration of aidl files for these classes is required. When converting from OS primitives to java Objects, the Creator class is used.
To write data, use the writeToParcel method of the Parcelable interface:
There is also an auxiliary method describeContents, its task is to describe special cases / states of the object which can be used for serialization and desirialization:
Methods for reading data were not worthy of putting them into the Parcelable interface, but the standard practice is to use Creator together with:
Activity starts the service (making it thus StartedService) in the onCreate method
At the same stage of the life cycle, it connects to the service:
The process of connecting to the service is asynchronous, it implements the implementation of the ServiceConnection interface. During a connection to the server, Activity is registered in the service as a message listener, using the implementation of IDataSourceServiceListener.Stub:
While StartedService is running, if the amount of free memory decreases to a certain threshold, the system can kill the service without warning. After that, the system must restart the service. Thus, in the onServiceDisconnected method, we again initialize the connection with the service.
I hope the laid out source codes will help developers familiarize themselves with AIDL. An archive with a complete example is here .
The main application is available for viewing in the Android Market .
White papers on AndroidDevelopers:
Services: developer.android.com/guide/topics/fundamentals/services.html
AIDL: developer.android.com/guide/developing/tools/aidl.html
It contains an example application with a service that is running in a separate process.
The article should be considered as:
- An example of the architecture of an application using remote Android Services and AIDL.
- Useful code examples.
- solely as an addition to the main documentation on Android Developers (see links at the end of the article).
Basic concepts
Service is a component of an Android application without a user interface, designed to perform resource-intensive and / or lengthy operations.
Types of Android Services
- Started - services that are launched by any other component of the application (Activity, BrodcastReceiver, Service) and work until they stop themselves or someone stops them.
- Bound (related) - a service that acts as a server in a client-server architecture. Such a service is created upon the first connection (request) from another component of the application. The service stops when the last client disconnects.
- A service can be both Started and Bound. Such a service is able to "live forever" and serve customer requests.
A service can be launched in a process separate from Activity.
Benefits:
- the maximum memory size is increased by 2 times, for example 32 MB / process (depending on the platform).
- GC behaves less aggressively if you have 2 processes with snapshot in N MB each than 1 process and 2 * N MB.
- standard advantages of Android services: background, independence from Activity, etc.
Disadvantages:
- Additional system resources for low-level serialization and deserialization.
- the need to control the life cycle of the process.
- bit more code.
Aidl
In a literal translation - the language for the description of Android interfaces. Used to describe the composition and decomposition of Java objects into OS primitives for direct transfer between processes.
AIDL files are very similar to standard interfaces in java with the exception of:
- You even need to import those aidl files that are in the same package.
- The oneway keyword in the void method declaration means that the method will be called asynchronously (the client does not wait for its execution).
- Only primitives, String, List, and Parcelable classes declared in other aidl files can be used.
Using AIDL, java code is automatically generated to generate stabs.
Application architecture
The application we developed is a gallery for Android that allows you to view photos from a memory card and photo-sharing networks.
The main tasks of the service in this application are: obtaining metadata (information about albums, photos, friends), monitoring their updates and everything else that is associated with them. The service constantly stores relevant information and is ready at any time to give it to the main Activity for display.
The following are key sections of code and the process of creating a primitive service is described:
The following AIDL files are used to communicate between the service and Activity:
IDataSourceService.aidl - service interface:
packagecom.umobisoft.habr.aidlexample.common;
import com.umobisoft.habr.aidlexample.common.IDataSourceServiceListener;
interfaceIDataSourceService{
voidloadAlbums(in IDataSourceServiceListener listener);
…
}
IDataSourceServiceListener.aidl - interface for listeners of messages from the service:
package com.umobisoft.habr.aidlexample.common;
import com.umobisoft.habr.aidlexample.common.pojo.Album;
interface IDataSourceServiceListener{
oneway void albumItemLoaded(in Album a);
}
Data is transmitted using two classes that implement the Parcelable interface - Album and Photo. The declaration of aidl files for these classes is required. When converting from OS primitives to java Objects, the Creator class is used.
To write data, use the writeToParcel method of the Parcelable interface:
@Override
public void writeToParcel(Parcel out, int flags) {
try{
out.writeLong(id);
out.writeString(name);
out.writeTypedList(photos);
}catch (Exception e) {
Log.e(TAG, "writeToParcel", e);
}
}
There is also an auxiliary method describeContents, its task is to describe special cases / states of the object which can be used for serialization and desirialization:
@Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
Methods for reading data were not worthy of putting them into the Parcelable interface, but the standard practice is to use Creator together with:
private void readFromParcel(Parcel in) {
try{
id = in.readLong();
name = in.readString();
photos.clear();
in.readTypedList(photos, Photo.CREATOR);
}catch (Exception e) {
Log.e(TAG, "readFromParcel", e);
}
}
Activity starts the service (making it thus StartedService) in the onCreate method
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
textView = (TextView)findViewById(R.id.album_text);
Intent serviceIntent = newIntent(this, DataSourceService.class);
startService(serviceIntent);
connectToService();
}
At the same stage of the life cycle, it connects to the service:
private void connectToService() {
Intent intent = newIntent(this, DataSourceService.class);
this.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
}
The process of connecting to the service is asynchronous, it implements the implementation of the ServiceConnection interface. During a connection to the server, Activity is registered in the service as a message listener, using the implementation of IDataSourceServiceListener.Stub:
private ServiceConnection serviceConnection = newServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i(TAG, "Service connection established");
serviceApi = IDataSourceService.Stub.asInterface(service);
try {
mainListener = newIDataSourceServiceListener.Stub() {
@Override
publicvoidalbumItemLoaded(final Album a) throwsRemoteException {
mToastHandler.post(new Thread(){
publicvoid run(){
Toast.makeText(HabrahabrAIDLExampleActivity.this, a.toString(), Toast.LENGTH_LONG).show();
textView.setText(a.toString());
}
});
}
};
serviceApi.loadAlbums(mainListener);
} catch (RemoteException e) {
Log.e(TAG, "loadAlbums", e);
}
}
@Override
publicvoidonServiceDisconnected(ComponentName name) {
Log.i(TAG, "Service connection closed");
serviceApi = null;
connectToService();
}
};
While StartedService is running, if the amount of free memory decreases to a certain threshold, the system can kill the service without warning. After that, the system must restart the service. Thus, in the onServiceDisconnected method, we again initialize the connection with the service.
I hope the laid out source codes will help developers familiarize themselves with AIDL. An archive with a complete example is here .
The main application is available for viewing in the Android Market .
White papers on AndroidDevelopers:
Services: developer.android.com/guide/topics/fundamentals/services.html
AIDL: developer.android.com/guide/developing/tools/aidl.html