AIDL (Android Interface Definition Language) is the Android interface definition language.
Recently, I was looking at the principle of Binder. In Android, AIDL is the classic implementation of Binder. First, record the steps to use AIDL.
1 Server Service
1.1 Use AndroidStudio to create aidl file
Then a page that allows you to modify the file name pops up, and the file name can be taken by yourself
After clicking Finish, the aidl file directory is as follows:
Then open the aidl folder directory and open the OperateNumInterface.aidl file just created:
Among them, NumBean is a newly created java class, the directory is as follows
NumBean must implement the Parcelable interface, the complete code is as follows
package com.sz.aidl_service_demo;
import android.os.Parcel;
import android.os.Parcelable;
public class NumBean implements Parcelable {
private String extraInfo;
private int num1;
private int num2;
public NumBean(int num1, int num2, String extraInfo) {
this.num1 = num1;
this.num2 = num2;
this.extraInfo = extraInfo;
}
protected NumBean(Parcel parcel) {
num1 = parcel.readInt();
num2 = parcel.readInt();
extraInfo = parcel.readString();
}
public String getExtraInfo() {
return extraInfo;
}
public void setExtraInfo(String extraInfo) {
this.extraInfo = extraInfo;
}
public int getNum1() {
return num1;
}
public void setNum1(int num1) {
this.num1 = num1;
}
public int getNum2() {
return num2;
}
public void setNum2(int num2) {
this.num2 = num2;
}
public static final
Creator<NumBean> CREATOR = new Creator<NumBean>() {
@Override
public NumBean createFromParcel(Parcel source) {
return new NumBean(source);
}
@Override
public NumBean[] newArray(int size) {
return new NumBean[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(num1);
dest.writeInt(num2);
dest.writeString(extraInfo);
}
}
Then create a NumBean.adil file in the aidl folder, as shown in the figure
At this time, you need to rebulid the project to generate the OperateNumInterface.java file. After the build is successful, the following directories will appear:
1.2 Create a Service implementation class
Create a class to implement Service, the location directory is as follows
OperateNumService.java detailed code:
package com.sz.aidl_service_demo;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import androidx.annotation.Nullable;
public class OperateNumService extends Service {
注释1:一定要先ReBuild项目,否则找不到OperateNumInterface
private IBinder iBinder = new OperateNumInterface.Stub() {
@Override
public int operateNum(NumBean numBean) throws RemoteException {
注释2:还记得aidl文件中我们自己定义的方法么,具体实现在这里
Log.i("tag", "num1=" + numBean.getNum1() + ",num2=" + numBean.getNum2() + ",ExtraInfo=" + numBean.getExtraInfo());
return numBean.getNum1() + numBean.getNum2();//我是将NumBean中两个数的和返回
}
};
@Nullable
@Override
public IBinder onBind(Intent intent) {
return iBinder;
}
}
Then don't forget to declare Service in the Mainfest file:
<service android:name=".OperateNumService">
<intent-filter>
<action android:name="com.aidl_service_demo.my_flag" />
</intent-filter>
</service>
The server is finished here.
2 Client
2.1 Copy the aidl folder of the server directly to the Client directory
2.2 New NumBean class
Note that the directory structure of the NumBean class should be the same as the directory structure of the Service side
Note that you need to ReBuild the project
2.3 Binding Service and sending data to receive and return results
These operations are performed in MainActivity, the code is as follows:
import androidx.appcompat.app.AppCompatActivity;
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.util.Log;
import android.view.View;
import android.widget.TextView;
import com.sz.aidl_service_demo.NumBean;
import com.sz.aidl_service_demo.OperateNumInterface;
public class MainActivity extends AppCompatActivity {
private TextView tv_operate_num_result;
private int operateResult = -1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_operate_num_result = findViewById(R.id.tv_operate_num_result);
}
注释1:按钮1 绑定Service
public void bindService(View view) {
Intent intentBind = new Intent();
intentBind.setAction("com.aidl_service_demo.my_flag");
intentBind.setPackage("com.sz.aidl_service_demo");
bindService(intentBind, serviceConnection, Context.BIND_AUTO_CREATE);
}
注释2:按钮2 向Service发送数据并接收返回数据展示
public void sendService(View view) {
NumBean numBean = new NumBean(160, 8, "i'm extra info");
if (operateNumInterface != null) {
try {
operateResult = operateNumInterface.operateNum(numBean);
} catch (RemoteException e) {
e.printStackTrace();
}
}
tv_operate_num_result.setText("Service 返回操作结果为: " + operateResult);
}
private OperateNumInterface operateNumInterface;
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i("tag", "onServiceConnected");
注释3:
operateNumInterface = OperateNumInterface.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
operateNumInterface = null;
}
};
}
1 Click the Bind Service button first, and the client prints the log as follows:
2 Then click the Send data to Service button
The service log is as follows:
The client interface is shown as follows: