What are the steps in creating a bounded service through AIDL?

Asked 10-Jan-2018
Viewed 386 times

1

What are the steps in creating a bounded service through AIDL?


1 Answer


0

a service in android can be used for the long-term running operation. these operations can be configured to run in the background. but by default service runs in the foreground. if you are using for an operation which requires resources to be used for a longer period of time then you should run in other thread

a bounded service is a service which bounds with the components to perform operations such as send request, receive a response, or perform interprocess communications (IPC). this is a client-server based interface. to implement binding service you need to call the onBind() method which returns iBinder interface object. this object can be used to interact with the client.

through aidl, we can implement bounded services. aidl stands for Android Interface Development Language.it provides the interface through which client and service can interact with each other . so their work is to decompose the objects into primitives so that operating system can understand


CREATE AIDL FILE

to begin with this implementation you need to first create the aidl file and this will automatically generate the iBinder interface. Here is an example of an aidl file.

// IRemoteService.aidl
package com.example.android;
// 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();
    /** a method which accepts some data with no return types
     */
    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
            double aDouble, String aString);
}

Save this .aidl file in your project's src/ directory and when you build your application, the SDK tools generate the IBinder interface file in your project's gen/ directory. The generated file name matches the .aidl file name, but with a .java extension. In the android studio, this process is generated by incremental build automatically.


CREATE INTERFACE

After building your application android SDK tool will generate a .java file which is named after your .aidl file. The interface generated will contain a subclass named stub which is actually the abstract implementation of the parent interface.

Here mBinder instance is created which will define RPC interface for the class. In the next step, this instance is exposed to the clients.

Few things needed to be kept in mind –

• RPC calls are synchronous so you need to call these services from another thread rather than the main thread to avoid app from being crash.

• The exceptions do not return to the caller.

• It is not guaranteed that incoming calls are executed in the main thread the synchronous behavior should be kept in mind.

private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {
    public int getPid(){
        return Process.myPid();
    }
    public void basicTypes(int anInt, long aLong, boolean aBoolean,
        float aFloat, double aDouble, String aString) {
        // Does nothing
    }
};

EXPOSING INTERFACE TO CLIENTS

Now after implementing the interface, we need clients to bind this service. To do this Service class is implemented and onBind() method is called which will return the instance of the class that will implement stub.

Now, to access this a client must calls bindService() to connect to this service. On the client's side onServiceConnected() callback receives the mBinder instance which is returned by the service's onBind() method.

public class RemoteService extends Service {
    @Override
    public void onCreate() {
        super.onCreate();
    }
    @Override
    public IBinder onBind(Intent intent) {
        // Return the interface
        return mBinder;
    }
    private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {
        public int getPid(){
            return Process.myPid();
        }
        public void basicTypes(int anInt, long aLong, boolean aBoolean,
            float aFloat, double aDouble, String aString) {
            // Does nothing
        }
    };
}