接着刚刚的一篇讲下使用AIDL传递对象的过程,AIDL在不导入其他包的情况下支持如下几种数据类型:
1. 基本数据类型(boolean、char、byte、int、long、float、double),注意:不支持short
2. String和CharSequence
3. List和Map
4. Parcelable:
传递对象必须要实现序列化,ADIL中序列化对象的流程如下:
1)序列化对象
2)建立对象的.aidl文件,名称要一样
3)建立.aidl文件,手动导入对象,声明对象是in还是out
接上一篇,看下工程结构,IDemoAidlInterface大家不用管,是上一篇的内容:
先看下怎么序列化对象,首先创建Person类,实现Parcelable接口,具体方法怎么使用看注释
/**
* 序列化
*
* @author yuzhentao
*/
public class Person implements Parcelable {
private String name;
private int age;
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 +
'}';
}
/**
* 内容接口描述,默认返回0就可以
*
* @return int
*/
@Override
public int describeContents() {
return 0;
}
/**
* 将对象序列化为一个Parcel对象
* 将类的数据写入外部提供的Parcel中,打包需要传递的数据到Parcel容器保存,以便从Parcel容器获取数据
*
* @param dest:Parcel
* @param flags:int
*/
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(age);
}
protected Person(Parcel in) {
this.name = in.readString();
this.age = in.readInt();
}
/**
* 实例化静态内部对象CREATOR实现接口Parcelable.Creator
*/
public static final Creator<Person> CREATOR = new Creator<Person>() {
/**
* 从Parcel容器中读取传递数据值,封装成Parcelable对象返回逻辑层
* @param in:Parcel
* @return Person
*/
@Override
public Person createFromParcel(Parcel in) {
return new Person(in);
}
/**
*创建一个类型为<T>,长度为size的数组,供外部类反序列化本类数组使用
* @param size:int
* @return Person[]
*/
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
}
然后建立对象的.aidl文件,名称要一样,写法是
package yuzhentao.aidldemo;
//必须这样写
parcelable Person;
然后建立.aidl文件,手动导入对象,声明对象是in还是out,这里切记一定要手动导入一下
package yuzhentao.aidldemo;
//手动导入
import yuzhentao.aidldemo.Person;
interface IParcelableAidlInterface {
//一定要带上in或者out,告诉这个Person是输入还是输出的
List<Person> add(in Person person);
}
接着就是修改Service的内容了,将接口更改一下即可,然后返回ArrayList<Person>
/**
* Aidl服务
*
* @author yuzhentao
*/
public class IDemoAidlService extends Service {
private ArrayList<Person> personList;
/**
* 当客服端绑定到服务端时会执行
*
* @param intent:Intent
* @return IBinder
*/
@Nullable
@Override
public IBinder onBind(Intent intent) {
// return iBinder;
personList = new ArrayList<>();
return iBinderPerson;
}
// private IBinder iBinder = new IDemoAidlInterface.Stub() {
// @Override
// public int add(int num1, int num2) throws RemoteException {
// Log.e("yzt", "收到远程请求,输入的参数是:" + num1 + "和" + num2);
// return num1 + num2;
// }
// };
private IBinder iBinderPerson = new IParcelableAidlInterface.Stub() {
@Override
public List<Person> add(Person person) throws RemoteException {
personList.add(person);
return personList;
}
};
}
服务端准备完毕,接着将这些文件包括复制到客户端,包名一定要一样,看下客户端的结构,同样请无视IDemoAidlInterface
客户端同样将接口修改一下,点击时实例化一个ArrayList<Person>,通过接口的方法传递到服务端,打印Log看下结果
/**
* 客户端
* 获取服务端
* .aidl必须和服务端的一样,包括包名,负责编译不通过
* 如果有序列化对象,连同包名也必须一样
*
* @author yuzhentao
*/
public class MainActivity extends Activity {
// private IDemoAidlInterface iDemoAidlInterface;
private IParcelableAidlInterface iParcelableAidlInterface;
/**
* 服务连接接口
*/
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {//连接服务时执行,ComponentName是bindService()指定的,IBinder是服务端的onBind()返回的
// iDemoAidlInterface = IDemoAidlInterface.Stub.asInterface(service);//返回IDemoAidlInterface,拿到了远程的服务的代理
iParcelableAidlInterface = IParcelableAidlInterface.Stub.asInterface(service);//返回IDemoAidlInterface,拿到了远程的服务的代理
}
@Override
public void onServiceDisconnected(ComponentName name) {//断开服务时执行
// iDemoAidlInterface = null;
iParcelableAidlInterface = null;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
bindService();//绑定服务
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(conn);//解绑服务
}
private void initView() {
// final EditText etNum1 = (EditText) findViewById(R.id.edittext_num1_activity_main);
// final EditText etNum2 = (EditText) findViewById(R.id.edittext_num2_activity_main);
// final EditText etResult = (EditText) findViewById(R.id.edittext_result_activity_main);
findViewById(R.id.button_activity_main).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// int num1 = Integer.parseInt(etNum1.getText().toString());
// int num2 = Integer.parseInt(etNum2.getText().toString());
// String result;
// try {
// result = iDemoAidlInterface.add(num1, num2) + "";//调用远程的服务
// etResult.setText(result);
// } catch (RemoteException e) {
// e.printStackTrace();
// etResult.setText("发生错误");
// }
try {
ArrayList<Person> personList = (ArrayList<Person>) iParcelableAidlInterface.add(new Person("yuzhentao", 25));
Log.e("yzt", personList.toString());
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
}
/**
* 绑定服务
* alt+command+m:提取方法
*/
private void bindService() {
Intent intent = new Intent();
intent.setComponent(new ComponentName("yuzhentao.aidldemo", "yuzhentao.aidldemo.IDemoAidlService"));//显式Intent
bindService(intent, conn, Context.BIND_AUTO_CREATE);//绑定服务
}
}
03-14 14:38:49.319 31540-31540/yuzhentao.aidldemoclient E/yzt: [Person{name='yuzhentao', age=25}]
这里没有效果图,在此感谢下慕课网
Demo地址:http://download.youkuaiyun.com/detail/qq_23940659/9467044