- 基础理论
- 运行效果
- 完整代码
- 注意事项
自定义的操作
在 AIDL 当中, 可以传递自定义的对象, 例如自己定义的 Person 类的对象, 也是可以传递的。 但是对于自定义的 Person 类, 需要做出相关的设置: (1)需要实现接口 android.os.Parcelable A. 重写了方法 describeContents B. 构造方法 Person C. 写数据的方法 writeToParcel D. 内部类的对象 CREATOR (2)需要定义读数据的方法 readFromParcel
关于自定义对象的操作
1. IN 输入 2. OUT 输出 3. INOUT 输入输出
加法的操作,关于服务端的处理 hello.svip.server
加法的操作,关于客户端的处理 hello.svip.client
关于 IN 的操作,关于服务端的展示数据 hello.svip.server
关于IN的操作,关于客户端的展示数据 hello.svip.client
关于 OUT 的操作,关于服务端的展示数据 hello.svip.server
关于 OUT 的操作,关于客户端的展示数据 hello.svip.client
关于 INOUT 的操作,关于服务端的展示数据 hello.svip.server
关于 INOUT 的操作,关于客户端的展示数据 hello.svip.client
// HelloAIDL.aidl
package hello.svip.server;
// Declare any non-default types here with import statements
import hello.svip.server.Person;
interface HelloAIDL {
//计算两个数据相加的和
int add(int num1,int num2);
//代表Person的数据值,由客户端输入
String inPersonInfo(in Person p);
//代表Person的数据值,由服务端设置
String outPersonInfo(out Person p);
//代表客户端和服务端 都可以设置
String inOutPersonInfo(inout Person p);
}
// Person.aidl package hello.svip.server; // Declare any non-default types here with import statements parcelable Person;
package hello.svip.server;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
public class Person implements Parcelable {
private String name;
private int age;
private final String TAG = "chc";
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + ''' +
", age=" + age +
'}';
}
//===============================================
@Override
public int describeContents() {
return 0;
}
protected Person(Parcel in) {
name = in.readString();
age = in.readInt();
}
// 写数据的信息
@Override
public void writeToParcel(Parcel dest, int flags) {
Log.i(TAG, "writeToParcel: 【服务端】被序列化...");
dest.writeString(name);
dest.writeInt(age);
}
// 读数据的信息
public void readFromParcel(Parcel source) {
Log.i(TAG, "readFromParcel: 【服务端】被反序列化...");
name = source.readString();
age = source.readInt();
}
public static final Creator CREATOR = new Creator() {
@Override
public Person createFromParcel(Parcel in) {
return new Person(in);
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
}
package hello.svip.server;
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 HelloService extends Service {
private static final String TAG = "chc";
@Nullable
@Override
public IBinder onBind(Intent intent) {
return iBindler;
}
IBinder iBindler = new HelloAIDL.Stub() {
@Override
public int add(int num1, int num2) throws RemoteException {
Log.i(TAG, "add: Service 的加法运算" + (num1 + num2));
return num1 + num2;
}
@Override
public String inPersonInfo(Person p) throws RemoteException {
String name = p.getName();
int age = p.getAge();
String message = "in:" + name + "," + age;
Log.i(TAG, "inPersonInfo: 进入的操作: " + message);
return message;
}
@Override
public String outPersonInfo(Person p) throws RemoteException {
String name = p.getName();
int age = p.getAge();
String message = "out:" + name + "," + age;
Log.i(TAG, "outPersonInfo: 退出的操作: " + message);
return message;
}
@Override
public String inOutPersonInfo(Person p) throws RemoteException {
String name = p.getName();
int age = p.getAge();
String message = "inout:" + name + "," + age;
Log.i(TAG, "inOutPersonInfo: 进退的操作: " + message);
return message;
}
};
}
// HelloAIDL.aidl
package hello.svip.server;
// Declare any non-default types here with import statements
import hello.svip.server.Person;
interface HelloAIDL {
//计算两个数据相加的和
int add(int num1,int num2);
//代表Person的数据值,由客户端输入
String inPersonInfo(in Person p);
//代表Person的数据值,由服务端设置
String outPersonInfo(out Person p);
//代表客户端和服务端 都可以设置
String inOutPersonInfo(inout Person p);
}
// Person.aidl package hello.svip.server; // Declare any non-default types here with import statements parcelable Person;
package hello.svip.server;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
public class Person implements Parcelable {
private String name;
private int age;
private final String TAG = "chc";
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + ''' +
", age=" + age +
'}';
}
//===============================================
@Override
public int describeContents() {
return 0;
}
protected Person(Parcel in) {
name = in.readString();
age = in.readInt();
}
// 写数据的信息
@Override
public void writeToParcel(Parcel dest, int flags) {
Log.i(TAG, "writeToParcel: 【客户端】被序列化...");
dest.writeString(name);
dest.writeInt(age);
}
// 读数据的信息
public void readFromParcel(Parcel source) {
Log.i(TAG, "readFromParcel: 【客户端】被反序列化...");
name = source.readString();
age = source.readInt();
}
public static final Creator CREATOR = new Creator() {
@Override
public Person createFromParcel(Parcel in) {
return new Person(in);
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
}
package hello.svip.client;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ComponentName;
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.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import hello.svip.server.HelloAIDL;
import hello.svip.server.Person;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "chc";
private EditText etName, etAge;
private TextView tvShow;
private Button btnBind, btnAdd, btnIn, btnOut, btnInOut;
private HelloAIDL aidl;
//绑定服务的操作
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
aidl = HelloAIDL.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
aidl = null;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.etName = this.findViewById(R.id.et_name);
this.etAge = this.findViewById(R.id.et_age);
this.tvShow = this.findViewById(R.id.tv_show);
this.btnBind = this.findViewById(R.id.btn_bind);
this.btnAdd = this.findViewById(R.id.btn_add);
this.btnIn = this.findViewById(R.id.btn_in);
this.btnOut = this.findViewById(R.id.btn_out);
this.btnInOut = this.findViewById(R.id.btn_inout);
//设置按钮的点击事件处理
this.btnBind.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction("this.is.aidl.action");
intent.setPackage("hello.svip.server");
bindService(intent, conn, BIND_AUTO_CREATE);
Toast.makeText(MainActivity.this,"服务绑定",Toast.LENGTH_LONG).show();
Log.i(TAG, "onClick: 绑定服务");
}
});
this.btnAdd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
String name = etName.getText().toString().trim();
String age = etAge.getText().toString().trim();
int num1 = Integer.parseInt(name);
int num2 = Integer.parseInt(age);
int result = aidl.add(num1, num2);
Log.i(TAG, "onClick: --> " + result);
tvShow.setText("结果是:" + result);
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
this.btnIn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
String name = etName.getText().toString().trim();
String age = etAge.getText().toString().trim();
Person p = new Person(name, Integer.parseInt(age));
String message = aidl.inPersonInfo(p);
Log.i(TAG, "onClick: --> " + message);
tvShow.setText("结果是:" + message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
this.btnOut.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
String name = etName.getText().toString().trim();
String age = etAge.getText().toString().trim();
Person p = new Person(name, Integer.parseInt(age));
String message = aidl.outPersonInfo(p);
Log.i(TAG, "onClick: --> " + message);
tvShow.setText("结果是:" + message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
this.btnInOut.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
String name = etName.getText().toString().trim();
String age = etAge.getText().toString().trim();
Person p = new Person(name, Integer.parseInt(age));
String message = aidl.inOutPersonInfo(p);
Log.i(TAG, "onClick: --> " + message);
tvShow.setText("结果是:" + message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(conn);
}
}
1. 客户端和服务端, 当中都需要拥有 HelloAIDL.aidl 文件 和 Person.aidl 文件 2. 客户端和服务端, 当中都需要拥有 Perosn.java 文件, 另外他们的是包名称都是 hello.svip.server.Person 文件
关于 Person.java 类的实现当中: 1、需要实现接口 android.os.Parcelable 2、除了自己的 getter 和 setter 方法外, 还需要有以下五部分内容: A. describeContents B. Person 新增构造方法 C. writeToParcel 写数据的方法 D. readFromParcel 读数据的方法 E. CREATOR 内部类的对象
其他两篇文章:
AIDL 基础体验(一)
https://chcsvip.blog.csdn.net/article/details/121273329
AIDL 基础体验(二)
https://chcsvip.blog.csdn.net/article/details/121350336



