如果在AIDL接口中传递自定义的类型,需要实现Parcelable接口,传输时可以序列号/反序列化对象,目标进程就可以还原对象了。
Java类型需要实现android.os.Parcelable接口
public interface Parcelable {
int CONTENTS_FILE_DESCRIPTOR = 1;
int PARCELABLE_WRITE_RETURN_VALUE = 1;
int describeContents();
void writeToParcel(Parcel var1, int var2);
public interface Creator<T> {
T createFromParcel(Parcel var1);
T[] newArray(int var1);
}
public interface ClassLoaderCreator<T> extends Creator<T> {
T createFromParcel(Parcel var1, ClassLoader var2);
}
}
// A Java Parcelable sample
class MyData implements Parcelable {
private String name;
protected MyData(Parcel in) {
name = in.readString();
}
public static final Creator<MyData> CREATOR = new Creator<MyData>() {
@Override
public MyData createFromParcel(Parcel in) {
return new MyData(in);
}
@Override
public MyData[] newArray(int size) {
return new MyData[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(name);
}
}
C++需要继承Parcelable(binder/Parcelable.h)
class Parcelable {
public:
virtual ~Parcelable() = default;
Parcelable() = default;
Parcelable(const Parcelable&) = default;
// Write |this| parcelable to the given |parcel|. Keep in mind that
// implementations of writeToParcel must be manually kept in sync
// with readFromParcel and the Java equivalent versions of these methods.
//
// Returns android::OK on success and an appropriate error otherwise.
virtual status_t writeToParcel(Parcel* parcel) const = 0;
// Read data from the given |parcel| into |this|. After readFromParcel
// completes, |this| should have equivalent state to the object that
// wrote itself to the parcel.
//
// Returns android::OK on success and an appropriate error otherwise.
virtual status_t readFromParcel(const Parcel* parcel) = 0;
}; // class Parcelable
使用Java Parcelable的例子
aidl文件内容:
// IMyServiceInterface.aidl
package com.my.pkg;
interface IMyServiceInterface {
void setJava(in com.my.pkg.JavaParcelable data);
// void setCpp(in com.my.pkg.CppParcelable data);
}
// JavaParcelable.aidl
package com.my.pkg;
parcelable JavaParcelable;
编译aidl文件:
$ aidl -I aidl/ -o java aidl/com/my/pkg/IMyServiceInterface.aidl
在java/com/my/pkg目录下生成IMyServiceInterface.java接口文件。
关于aidl命令行编译可参考:Android AIDL系列 1 - 手动编译aidl文件
注意:没有JavaParcelable.java源文件就可以生成接口文件。C++不是这样。
使用C++ Parcelable的例子
aidl文件内容
// IMyServiceInterface.aidl
package com.my.pkg;
interface IMyServiceInterface {
// void setJava(in com.my.pkg.JavaParcelable data);
void setCpp(in com.my.pkg.CppParcelable data);
}
// CppParcelable.aidl
package com.my.pkg;
parcelable CppParcelable cpp_header "CppParcelable.h";
// CppParcelable.h,空文件即可
编译aidl文件生成c++接口文件:
$ aidl -I aidl/ -h cpp_parcel -o cpp_parcel --lang=cpp aidl/com/my/pkg/IMyServiceInterface.aidl
.h和.cpp文件生成在cpp_parcel/com/my/pkg目录下。
在生成c++接口时,对应的parcel文件中,aidl文件定义中需要用cpp_header关键字指定对应类型的头文件。
实际试验aidl编译过程不校验头文件的内容,哪怕是空文件也可以正常编译通过,生成所需头文件和源码文件。
关于aidl命令行编译可参考:Android AIDL系列 1 - 手动编译aidl文件