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!