Friday, September 23, 2016

Inter Process Communication - Android Interface Definition Language

Hi .... Dear All ....  Today I am uploading a superb example of Inter Process Communication in Android.
In this example i am using a popular concept of AIDL.
What is Interprocess Communication??? 


In IPC a method is called by an activity or other application component, but executed remotely (in another process), with any result returned back to the caller.
This entails decomposing a method call and its data to a level the operating system can understand, transmitting it from the local process and address space to the remote process and address space, then reassembling and reenacting the call there.
 Return values are then transmitted back to caller.
 Android provides all the code to perform these IPC transactions, so you can focus on defining and implementing the RPC programming interface.
To implement  IPC, your application must bind to a service, using bindService().

Android Interface Definition Language (AIDL)

It allows you to define the programming interface that both the client and service agree upon in order to communicate with each other using interprocess communication.

On Android, one process cannot normally access the memory of another process. 

So to talk, they need to decompose their objects into primitives that the operating system can understand, and marshall the objects across that boundary for you. 

The code to do that marshalling is tedious to write, so Android handles it for you with AIDL.

See my example .....

A. How to define AIDL .... steps 
-> first create a aidl folder in res folder.
-> In this folder create a aidl file.
-> This file is actually interface so declare all methods here.
-> After done all these steps please Rebuild project once.
see my aidl file named as   IRemSer.aidl

// IRemSer.aidlpackage aidl;

// Declare any non-default types here with import statements
interface IRemSer {
            String sayHello(String msg);
            int add_num(int a,int b);
}  

B. Create a service to implement this aidl interface 
Register service in manifest file 
In  my example i had created service named as DemoService.java as
package com.example.ravigodara.ipcaidl;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.annotation.Nullable;

import aidl.IRemSer;


public class DemoService extends Service   {
    @Nullable    @Override

    public IBinder onBind(Intent intent) {
        return mBinder;
    }
 private final IRemSer.Stub mBinder = new IRemSer.Stub() {
     @Override     public String sayHello(String msg) throws RemoteException {
         return "Hello"+ msg;
     }

     @Override

     public int add_num(int a, int b) throws RemoteException {
         return (a+b);
     }

 };
}

C. Create you MainActivity and call the service 
In my example i had created MainActivity.java as 
package com.example.ravigodara.ipcaidl;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

import aidl.IRemSer;

public class DemoSerAct extends AppCompatActivity {

    IRemSer mIRemSer;
    Intent intent;
    EditText first,second,res;
    int fnum,snum,result;
    ServiceConnection scon = new ServiceConnection() {
        @Override

        public void onServiceConnected(ComponentName name, IBinder service) {
            mIRemSer = IRemSer.Stub.asInterface(service);
            startService(intent);
        }

        @Override

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

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        first  = (EditText) findViewById(R.id.editText);
        second  = (EditText) findViewById(R.id.editText2);
        res  = (EditText) findViewById(R.id.editText3);



    }
    public void startServ(View view)
    {
        fnum = Integer.parseInt(first.getText().toString());
        snum = Integer.parseInt(second.getText().toString());
        intent=new Intent(this,DemoService.class);
        bindService(intent, scon, Context.BIND_AUTO_CREATE);
    }
    public void stopServ(View view)
    {
        unbindService(scon);
    }
    public void callSer(View view)
    {
        String retmsg = null;
        try {
            retmsg = mIRemSer.sayHello("Godara");
            result = mIRemSer.add_num(fnum,snum);
            Log.d("ravi",String.valueOf(result));
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        Toast.makeText(this,"Sevice Returned Message "+retmsg,
                                          Toast.LENGTH_LONG).show();
        res.setText(String.valueOf(result));
    }
}

D. The layout file is like activity_main.xml as 

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    tools:context="com.example.ravigodara.ipcaidl.MainActivity">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="StartService"
        android:id="@+id/button1"
        android:onClick="startServ"
        android:layout_alignBaseline="@+id/button"
        android:layout_alignBottom="@+id/button"
        android:layout_alignParentStart="true" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="StopService"
        android:id="@+id/button2"
        android:onClick="stopServ"
        android:layout_alignTop="@+id/button1"
        android:layout_alignParentEnd="true" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="callSer"
        android:text="CallSer"
        android:id="@+id/button"
        android:layout_below="@+id/editText2"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="54dp" />

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/editText"
        android:layout_alignParentTop="true"
        android:layout_alignParentStart="true"
        android:layout_alignEnd="@+id/button2"
        android:hint="First Number"/>

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/editText2"
        android:layout_below="@+id/editText"
        android:layout_alignParentStart="true"
        android:layout_alignEnd="@+id/editText"
        android:hint="Second Number"/>

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/editText3"
        android:layout_below="@+id/button1"
        android:layout_marginTop="75dp"
        android:layout_alignParentStart="true"
        android:layout_alignEnd="@+id/button2"
        android:hint="Result....."/>
</RelativeLayout>   

Output would be like this 
First start service then call service 
A.    



B.   


No comments:

Post a Comment