Service in Android part3

In my last tutorial, I have addressed the basic of services of both types of Started and Bound service. I will recommend checking my last tutorial link before reading this post. Here is the link of Service in Android part1 and Service in Android part2. Thanks for reading.

Wow, Today we got one more day to learn something new about the bound service feature. In this category Today, We will learn about the AIDL.

 AIDL 

AIDL means android interface definition language.It can process any task remotely by using IPC technique. Android has a strong mechanism to communicate between service and client through IPC technique. AIDL process the data between clients remotely and safely only thing is required that client should be bind with this services. AIDL support to process the generic data by using the Parcelable. Data processing through Parcelable is fast in IPC mechanism. Different process means I am talking about the communication between two different applications.

Let's take a simple word to define AIDL IPC mechanism, suppose you have App1 consider as a remote server that running AIDL service. What does this service? it gets the list of users information of table and process data to the client or any business logic that get information from the client and do some task and give a response back to the client (It means App2). Here the user model should be Parcelable for fast communication.

I think it's big complex example, Let's give another simple example to explain. I want to multiply for given two numbers. I will pass two different numbers as input and will tell to AIDL service to give the result as a response back to me. Ohh Wow This is pretty simple and easy to understand.  I took simple task here but it can take any long background task to the process, for example, downloading any audio or video files from the server.
For communication with two different apps or process, I need to create the AIDL file in the same package of both apps. Why AIDL is required on client side also it will create the copy of proxy for remote access.

Let's create two different android studio project for App1 and App2. 

MultiplyNumberAidl.aidl

   
// MultiplyNumberAidl.aidl
package com.example.testapp;

// Declare any non-default types here with import statements

interface MultiplyNumberAidl {

    int multiply(in int firstNumber, in int secondNumber);
}


AidlService.java

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

import com.example.testapp.MultiplyNumberAidl;

/**
 * Created by sunil on 4/03/2017.
 */

public class AidlService extends Service{

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return new MultiplyNumberAidl.Stub() {
            @Override
            public int multiply(int firstNumber, int secondNumber) throws RemoteException {
                return (firstNumber * secondNumber);
            }
        };
    }
}

You need to set the build and sync to access the aidl file.

build.gradle app level

   
 sourceSets {
        main {
            aidl.srcDirs = ['src/main/aidl']
        }
    }

Add the service in AndroidManifest.xml file.

   
       <service android:name=".bindservice.ipc.aidl.AidlService" android:process=":remote">
            <intent-filter>
             <action android:name="com.example.testapp.bindservice.ipc.aidl.MultiplyNumberAidl" />
           </intent-filter>
        </service>
Now in App2, I will try to access the service to get the result. You need to bind via explicit intent service with the client by ServiceConnection.

MultiplyNumberAidlActivity.java

   
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.example.contentprovideraccess.R;
import com.example.testapp.MultiplyNumberAidl;

import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;

/**
 * Created by sunil on 04/03/2017.
 */

public class MultiplyNumberAidlActivity extends AppCompatActivity {

    @BindView(R.id.editText_First)
    EditText firstNumEditText;
    @BindView(R.id.editText_Second)
    EditText secondNumEditText;
    @BindView(R.id.addButton)
    Button btnAdd;

    MultiplyNumberAidl aidlService;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_aidl);
        ButterKnife.bind(this);

        initView();
    }

    private void initView() {

        btnAdd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String firstNumber = firstNumEditText.getText().toString().trim();
                String secondNumber = secondNumEditText.getText().toString().trim();
                int multiply= -1;
                if (firstNumber.isEmpty() && secondNumber.isEmpty()){
                    Toast.makeText(MultiplyNumberAidlActivity.this, "Please enter first and second number.", Toast.LENGTH_SHORT).show();
                }else{
                    try {
                        multiply =  aidlService.multiply(Integer.valueOf(firstNumber), Integer.valueOf(secondNumber));
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                    Toast.makeText(MultiplyNumberAidlActivity.this, ""+multiply, Toast.LENGTH_SHORT).show();
                }
            }
        });

    }

    @Override
    protected void onStart() {
        super.onStart();
        Intent intent = new Intent("com.example.testapp.bindservice.ipc.aidl.MultiplyNumberAidl");
        Intent updateIntent = createExplicitFromImplicitIntent(MultiplyNumberAidlActivity.this, intent);
        bindService(updateIntent, serviceConnection, Context.BIND_AUTO_CREATE);

    }

    public static Intent createExplicitFromImplicitIntent(Context context, Intent implicitIntent) {
        //Retrieve all services that can match the given intent
        PackageManager pm = context.getPackageManager();
        List resolveInfo = pm.queryIntentServices(implicitIntent, 0);

        //Make sure only one match was found
        if (resolveInfo == null || resolveInfo.size() != 1) {
            return null;
        }

        //Get component info and create ComponentName
        ResolveInfo serviceInfo = resolveInfo.get(0);
        String packageName = serviceInfo.serviceInfo.packageName;
        String className = serviceInfo.serviceInfo.name;
        ComponentName component = new ComponentName(packageName, className);

        //Create a new intent. Use the old one for extras and such reuse
        Intent explicitIntent = new Intent(implicitIntent);

        //Set the component to be explicit
        explicitIntent.setComponent(component);

        return explicitIntent;
    }

    ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            aidlService =  MultiplyNumberAidl.Stub.asInterface(service);
        }

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

activity_aidl.xml

   
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="10dp">

    <EditText
        android:maxLength="3"
        android:inputType="number"
        android:id="@+id/editText_First"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Enter First Number"/>

    <EditText
        android:maxLength="3"
        android:inputType="number"
        android:layout_marginTop="10dp"
        android:layout_below="@+id/editText_First"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/editText_Second"
        android:hint="Enter Second Number"/>

   <Button
        android:layout_marginTop="10dp"
        android:layout_below="@+id/editText_Second"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Multiply"
        android:id="@+id/addButton"
        android:background="@color/colorPrimary"
        android:textColor="#fff"/>

</RelativeLayout>
Here is snapshot to understand.


Wow AIDL is the really awesome feature of service that running in the background in multi-thread environment and its IPC mechanism is very strong to communicate remotely.

Thanks for reading this post.

No comments:

Post a Comment

Debug Database in Android

In my last tutorial, we have learned how we can use persistence database in android. We also understood which database wrapper we can use...

Contact Me

Name

Email *

Message *