The Use of AIDL--Implementing Cross-process Communication

AIDL (Android Interface Definition Language) is an Android interface definition language. Simply speaking, in the process of Android development, when encountering problems of multi-process development or inter-process communication, it can be implemented simply and quickly. The following describes the implementation steps of cross-process communication using AIDL.
1. Create an empty project called AIDLDemo, which starts with MainActivity as a Java file.
2. Create a folder named aidl in a directory level with java, as shown below.

3. Create an AIDL file under the Aidl folder, you can right-click the Aidl folder, find the AIDL in the new, Click to create the Aidl file, named IRemoteService, then generate the same directory structure as the java file under the Aidl folder, which contains an interface IRemoteService.

// IRemoteService.aidl
package com.example.administrator.aidldemo;

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

interface IRemoteService {

    int getPid();//Self-defined method
    /**
     * 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);
}

4. If there are no errors in the process of creating the Aidl file, the generated Java class will be found in AIDLDemo app build generated source aidl debug com example administrator aidldemo IRemoteService. java, which contains an abstract static class Stub, representing a Binder object. If there is no build, click ReBuild Project of Build to refresh the project.

5. At this time, the basic conditions of AIDL are ready, and we need to create the client and the server, in which the client is Active, and the server needs to create a Service to implement. First, we need to create a RemoteService class as follows. We define an IRemoteService.Stub object in it, and implement the method we defined in the Aidl interface. . The Binder object is returned to the client Activity through the onBind method of Service. Note that the process of Service needs to be set to android:process=": remote" in the manifest file, where ": remote" can be set by itself.

package com.example.administrator.aidldemo;

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

public class RemoteService extends Service {
    public RemoteService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        return binder;
    }

    private final IRemoteService.Stub binder = new IRemoteService.Stub() {

        @Override
        public int getPid() throws RemoteException {
            return Process.myPid();
        }


        @Override
        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
        }
    };
}

6. What the client MainActivity needs to do is to bindService and create a Service Connection object in two steps.

package com.example.administrator.aidldemo;

import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.Process;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent = new Intent();
        intent.setClass(this,RemoteService.class);
        bindService(intent,connection, Service.BIND_AUTO_CREATE);
    }
    private IRemoteService remoteService;
    private ServiceConnection connection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            remoteService = IRemoteService.Stub.asInterface(iBinder);
            try {
                Log.d("Client Id:", Process.myPid()+"");
                Log.d("Remote Id:",remoteService.getPid()+"");
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            remoteService = null;
        }
    };
}

7. By using AIDL, we can realize the communication between MainActivity and RemoteService, which are two components in different processes. The effect is as follows, you can see the pid of different processes.

In addition, sometimes we need to transfer our own defined Parcelable objects between processes, as follows.
1. Create a class MyProcess that implements Parcelable under the Java path. Most of the code is self-generated, just add your own data type in the following way.

package com.example.administrator.aidldemo;

import android.os.Parcel;
import android.os.Parcelable;

/**
 * Created by Administrator on 2018/3/18.
 */

public class MyProcess implements Parcelable {
    public int pid;
    public String name;

    public MyProcess(int id,String na) {
        pid = id;
        name = na;
    }

    protected MyProcess(Parcel in) {
        pid = in.readInt();
        name = in.readString();
    }

    public static final Creator<MyProcess> CREATOR = new Creator<MyProcess>() {
        @Override
        public MyProcess createFromParcel(Parcel in) {
            return new MyProcess(in);
        }

        @Override
        public MyProcess[] newArray(int size) {
            return new MyProcess[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        parcel.writeInt(pid);
        parcel.writeString(name);
    }
}

2. Add a file under the Aidl path, named MyProcess.aidl.

package com.example.administrator.aidldemo;
parcelable MyProcess;

3. Create an Aidl file IMyProcess under the Aidl path and use MyProcess, your own data type. Note that you need to import this class, which is the basic requirement of using AIDL.

// IMyProcess.aidl
package com.example.administrator.aidldemo;

// Declare any non-default types here with import statements
import com.example.administrator.aidldemo.MyProcess;
interface IMyProcess {
    MyProcess getMyProcess(in int p);
    /**
     * 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);
}

4. The custom object has been partially completed here. The rest of the process can refer to the above, such as defining a binder2 in the RemoteService on the server side, and obtaining a MyProcess object through the getMyProcess method defined in the IMyProcess interface.

private final IMyProcess.Stub binder2 = new IMyProcess.Stub() {


        @Override
        public MyProcess getMyProcess(int p) throws RemoteException {
            return new MyProcess(p,"jacket_Xu");
        }

        @Override
        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {

        }
    };

The use of AIDL is basically the same, of course, there are other contents such as Aidl data flow standard in, out,inout use will be explained later.
End!

Keywords: Android Java REST

Added by brandye71 on Sat, 18 May 2019 17:45:14 +0300