Search This Blog

Wednesday 13 March 2013

Binding service using Android Interface DefinitionLanguage (.aidl) in android

Binding service using iBinder an Messanger already discussesd. Third and most complicated way is binding service using Android Interface Definition Language (AIDL). Its rarely use and hard to implement. So this post simply will show you how to create one connection using Android Interface Definition Language (AIDL) between activity and service

 When to use Android Interface Definition Language (AIDL)

Using AIDL is necessary only if you allow clients from different applications to access your service for IPC and want to handle multithreading in your service. If you do not need to perform concurrent IPC across different applications, you should create your interface by implementing a Binder or, if you want to perform IPC, but do not need to handle multithreading, implement your interface using a Messenger. Knowledge Required you should read about binding service using IBinder and Messanger

 Steps 1) create .aidl interface. Create one file name IRemoteService.aidl and keep inside your main package


 // IRemoteService.aidl  
 package com.example.locationmanager;  
 // Declare any non-default types here with import statements  
 /** Example service interface */  
 interface IRemoteService {  
 /** Request the process ID of this service, to do evil things with it. */  
 int getPid();  
 /** Demonstrates some basic types that you can use as parameters  
 * and return values in AIDL.  
 */  
 void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,  
 double aDouble, String aString);  
 }  

When you build your application IRemoteService.aidl changes into IRemoteService.java like this. You can find this inside bin folder

 // Declare any non-default types here with import statements  
 /** Example service interface */  
 public interface IRemoteService extends android.os.IInterface {  
 /** Local-side IPC implementation stub class. */  
 public static abstract class Stub extends android.os.Binder implements  
 com.example.locationmanager.IRemoteService {  
 private static final java.lang.String DESCRIPTOR = "com.example.locationmanager.IRemoteService";  
 /** Construct the stub at attach it to the interface. */  
 public Stub() {  
 this.attachInterface(this, DESCRIPTOR);  
 }  
 /**  
 * Cast an IBinder object into an  
 * com.example.locationmanager.IRemoteService interface, generating a  
 * proxy if needed.  
 */  
 public static com.example.locationmanager.IRemoteService asInterface(  
 android.os.IBinder obj) {  
 if ((obj == null)) {  
 return null;  
 }  
 android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);  
 if (((iin != null) && (iin instanceof com.example.locationmanager.IRemoteService))) {  
 return ((com.example.locationmanager.IRemoteService) iin);  
 }  
 return new com.example.locationmanager.IRemoteService.Stub.Proxy(  
 obj);  
 }  
 @Override  
 public android.os.IBinder asBinder() {  
 return this;  
 }  
 @Override  
 public boolean onTransact(int code, android.os.Parcel data,  
 android.os.Parcel reply, int flags)  
 throws android.os.RemoteException {  
 switch (code) {  
 case INTERFACE_TRANSACTION: {  
 reply.writeString(DESCRIPTOR);  
 return true;  
 }  
 case TRANSACTION_getPid: {  
 data.enforceInterface(DESCRIPTOR);  
 int _result = this.getPid();  
 reply.writeNoException();  
 reply.writeInt(_result);  
 return true;  
 }  
 case TRANSACTION_basicTypes: {  
 data.enforceInterface(DESCRIPTOR);  
 int _arg0;  
 _arg0 = data.readInt();  
 long _arg1;  
 _arg1 = data.readLong();  
 boolean _arg2;  
 _arg2 = (0 != data.readInt());  
 float _arg3;  
 _arg3 = data.readFloat();  
 double _arg4;  
 _arg4 = data.readDouble();  
 java.lang.String _arg5;  
 _arg5 = data.readString();  
 this.basicTypes(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5);  
 reply.writeNoException();  
 return true;  
 }  
 }  
 return super.onTransact(code, data, reply, flags);  
 }  
 private static class Proxy implements  
 com.example.locationmanager.IRemoteService {  
 private android.os.IBinder mRemote;  
 Proxy(android.os.IBinder remote) {  
 mRemote = remote;  
 }  
 @Override  
 public android.os.IBinder asBinder() {  
 return mRemote;  
 }  
 public java.lang.String getInterfaceDescriptor() {  
 return DESCRIPTOR;  
 }  
 /**  
 * Request the process ID of this service, to do evil things with  
 * it.  
 */  
 @Override  
 public int getPid() throws android.os.RemoteException {  
 android.os.Parcel _data = android.os.Parcel.obtain();  
 android.os.Parcel _reply = android.os.Parcel.obtain();  
 int _result;  
 try {  
 _data.writeInterfaceToken(DESCRIPTOR);  
 mRemote.transact(Stub.TRANSACTION_getPid, _data, _reply, 0);  
 _reply.readException();  
 _result = _reply.readInt();  
 } finally {  
 _reply.recycle();  
 _data.recycle();  
 }  
 return _result;  
 }  
 /**  
 * Demonstrates some basic types that you can use as parameters and  
 * return values in AIDL.  
 */  
 @Override  
 public void basicTypes(int anInt, long aLong, boolean aBoolean,  
 float aFloat, double aDouble, java.lang.String aString)  
 throws android.os.RemoteException {  
 android.os.Parcel _data = android.os.Parcel.obtain();  
 android.os.Parcel _reply = android.os.Parcel.obtain();  
 try {  
 _data.writeInterfaceToken(DESCRIPTOR);  
 _data.writeInt(anInt);  
 _data.writeLong(aLong);  
 _data.writeInt(((aBoolean) ? (1) : (0)));  
 _data.writeFloat(aFloat);  
 _data.writeDouble(aDouble);  
 _data.writeString(aString);  
 mRemote.transact(Stub.TRANSACTION_basicTypes, _data,  
 _reply, 0);  
 _reply.readException();  
 } finally {  
 _reply.recycle();  
 _data.recycle();  
 }  
 }  
 }  
 static final int TRANSACTION_getPid = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);  
 static final int TRANSACTION_basicTypes = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);  
 }  
 /** Request the process ID of this service, to do evil things with it. */  
 public int getPid() throws android.os.RemoteException;  
 /**  
 * Demonstrates some basic types that you can use as parameters and return  
 * values in AIDL.  
 */  
 public void basicTypes(int anInt, long aLong, boolean aBoolean,  
 float aFloat, double aDouble, java.lang.String aString)  
 throws android.os.RemoteException;  
 }  

Step 2) Implement IRemoteService.aidl inside your service. So first create one service class name AidlService.java here

 import android.app.Service;  
 import android.content.Intent;  
 import android.os.IBinder;  
 import android.os.RemoteException;  
 public class AidlService extends Service {  
 @Override  
 public void onCreate() {  
 super.onCreate();  
 }  
 @Override  
 public IBinder onBind(Intent arg0) {  
 return mBinder.asBinder();  
 }  
 private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {  
 @Override  
 public int getPid() throws RemoteException {  
 return 0;  
 }  
 @Override  
 public void basicTypes(int anInt, long aLong, boolean aBoolean,  
 float aFloat, double aDouble, String aString)  
 throws RemoteException {  
 }  
 };  
 }  

Step 3) ServiceConnection class allow to create connection between IRemoteService and your service class. So bind your service inside your activity. Change your main activity code to as follows

 import android.app.Activity;  
 import android.content.ComponentName;  
 import android.content.Context;  
 import android.content.Intent;  
 import android.content.ServiceConnection;  
 import android.os.Bundle;  
 import android.os.IBinder;  
 public class BindAidlActivity extends Activity {  
 @Override  
 protected void onCreate(Bundle savedInstanceState) {  
 super.onCreate(savedInstanceState);  
 bindService();  
 }  
 public void bindService() {  
 Intent intent = new Intent(this, AidlService.class);  
 bindService(intent, new ConnectService(), Context.BIND_AUTO_CREATE);  
 }  
 public void stoppingService() {  
 Intent intent = new Intent(this, AidlService.class);  
 stopService(intent);  
 }  
 IRemoteService uAidlService;  
 public class ConnectService implements ServiceConnection {  
 @Override  
 public void onServiceConnected(ComponentName name, IBinder service) {  
 uAidlService = IRemoteService.Stub.asInterface(service);  
 }  
 @Override  
 public void onServiceDisconnected(ComponentName name) {  
 /**  
 * Called when service disconnected  
 */  
 }  
 }  
 }  

Download All Service Binding Example

No comments:

Post a Comment

Feedback always help in improvement. If you have any query suggestion feel free to comment and Keep visiting my blog to encourage me to blogging

Android News and source code