Monday, August 6, 2012

Android - Bind Service and expose APIs using AIDL

Android - Bind Service and expose APIs using AIDL.

In this , I am trying to demonstrate a sample for the AIDL. For those, who needs to know more theoratical part of it, http://developer.android.com/guide/components/aidl.html.

For me, AIDL is a way to expose a set of APIs, which we can use it from other application by binding this service, in which we implemented the set of APIs.

Will start the sample code now.

First we create the .aidl file.

IAIDLFunctions.aidl

package com.test.aidlfunctions;
  
interface IAIDLFunctions {
 int add(in int num1,in int num2);
 double divide (in int num1,in int num2);
 int mul(in int num1,in int num2);
 int sub(in int num1,in int num2); 
}


And In Service, we implement the functions in onBind(),
package com.test.aidlfunctions;

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

public class AIDLFunctionService extends Service {

 @Override
 public void onCreate() {
  super.onCreate();
 }

 @Override
 public IBinder onBind(Intent intent) {
  return new IAIDLFunctions.Stub() {

   @Override
   public int sub(int num1, int num2) throws RemoteException {
    return (num1 - num2);
   }

   @Override
   public int mul(int num1, int num2) throws RemoteException {
    return (num1 * num2);
   }

   @Override
   public double divide(int num1, int num2) throws RemoteException {
    return (num1 / num2);
   }

   @Override
   public int add(int num1, int num2) throws RemoteException {
    return (num1 + num2);
   }
  };
 }

 @Override
 public void onDestroy() {
  super.onDestroy();
 }
}


And In Activity, we bind the service and and initialize the IAIDLFunctions object and call the api.
package com.test.aidlfunctions;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class AIDLFunctionsActivity extends Activity implements OnClickListener {
 /** Called when the activity is first created. */
 private EditText edNum1;
 private EditText edNum2;
 private Button btnAdd;
 private Button btnSub;
 private Button btnMul;
 private Button btnDiv;
 private IAIDLFunctions iFunctions;
 private AIDLFunctionServiceConnection serviceConnection;

 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  initAndBindService();
  edNum1 = (EditText) findViewById(R.id.num1);
  edNum2 = (EditText) findViewById(R.id.num2);
  btnAdd = (Button) findViewById(R.id.add);
  btnSub = (Button) findViewById(R.id.sub);
  btnMul = (Button) findViewById(R.id.mul);
  btnDiv = (Button) findViewById(R.id.div);
  btnAdd.setOnClickListener(this);
  btnSub.setOnClickListener(this);
  btnMul.setOnClickListener(this);
  btnDiv.setOnClickListener(this);
 }

 private void initAndBindService() {
  serviceConnection = new AIDLFunctionServiceConnection();
  Intent intent = new Intent();
//  intent.setClass(this, AIDLFunctionService.class);
  intent.setClassName("com.test.aidlfunctions", "com.test.aidlfunctions.AIDLFunctionService");
//  intent.setClassName(AIDLFunctionService.class.getPackage().getName(),
//    AIDLFunctionService.class.getSimpleName());
  try {
   boolean ret = bindService(intent, serviceConnection,
     BIND_AUTO_CREATE);
   Toast.makeText(this, "Connected : " + ret, Toast.LENGTH_LONG).show();
  } catch (Exception e) {
   // TODO: handle exception
  }
  
 }

 @Override
 public void onClick(View v) {
  int numOne = Integer.parseInt(edNum1.getText().toString().trim());
  int numTwo = Integer.parseInt(edNum2.getText().toString().trim());
  switch (v.getId()) {
  case R.id.add:
   try {
    Toast.makeText(this,
      "Result : " + iFunctions.add(numOne, numTwo),
      Toast.LENGTH_SHORT).show();
   } catch (RemoteException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
   break;
  case R.id.sub:
   try {
    Toast.makeText(this,
      "Result : " + iFunctions.sub(numOne, numTwo),
      Toast.LENGTH_SHORT).show();
   } catch (RemoteException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
   break;
  case R.id.mul:
   try {
    Toast.makeText(this,
      "Result : " + iFunctions.mul(numOne, numTwo),
      Toast.LENGTH_SHORT).show();
   } catch (RemoteException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
   break;
  case R.id.div:
   try {
    Toast.makeText(this,
      "Result : " + (double)iFunctions.divide(numOne, numTwo),
      Toast.LENGTH_SHORT).show();
   } catch (RemoteException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
   break;
  }
 }

 @Override
 protected void onDestroy() {
  unbindService(serviceConnection);
  serviceConnection = null;
  super.onDestroy();
 }

 class AIDLFunctionServiceConnection implements ServiceConnection {

  @Override
  public void onServiceConnected(ComponentName name, IBinder service) {
   iFunctions = IAIDLFunctions.Stub.asInterface(service);
  }

  @Override
  public void onServiceDisconnected(ComponentName name) {
   iFunctions = null;
  }

 }
}

2 comments:

  1. Can we have multiple aidls?
    Example: one is add.aidl and another is subtract.aidl

    ReplyDelete
  2. thank you ,keep posting new ideas..

    ReplyDelete