Android AIDL使用之Parcelable对象

安卓AIDL通信中自定义Parcelable对象使用

Views: 643
0 0
Read Time:2 Minute, 12 Second

parcel是安卓binder通信中的消息载体,通过IBinder进行传递。Parcel的源码实现为android.os.Parcel,继承自java.lang.object。涉及的相关源码为:

base/core/java/android/os/Parcel.java //java 实现
frameworks/base/core/jni/android_os_Parcel.cpp //JNI实现
frameworks/native/libs/binder/Parcel.cpp // C++实现
frameworks/native/libs/binder/include/binder/Parcelable.h //c++ 头文件
base/core/java/android/os/Parcel.java //java 实现 frameworks/base/core/jni/android_os_Parcel.cpp //JNI实现 frameworks/native/libs/binder/Parcel.cpp // C++实现 frameworks/native/libs/binder/include/binder/Parcelable.h //c++ 头文件

有些时候我们需要在binder中传递自定义的数据类型或者类,此时需要使该类实现Parcelable接口,如果我们是在C++程序与Java程序中进行传递,那么C++与Java侧都需要实现Parcelable接口。支持Parcelbale接口十分重要,Android系统可通过该接口将对象分解成各进程支持的原生类型。这里需要注意的是,Parcel是实体类,而Parcelable是接口。

自己实现Parcelable接口,根据后端语言的不同,具体实现上也存在差异。这里将分别以Java和C++两种后端语言给出示例。

Java

1.定义aidl文件,如myParcelable.aidl,这里其实有约定俗成的命名方式,不需要像定义接口那样以I开头,并且其内容如下:

package android.com.example;
parcelable myParcelable;
package android.com.example; parcelable myParcelable;

2.实现Parcelable接口中的int describeContents()、void writeToParcel(Parcel dest,int flags)以及为myParcelable类添加CREATOR静态字段,实现Parcelable.Creator接口的对象,这里给出示例代码:

import android.os.Parcel;
import android.os.Parcelable;
public final class myParcelable implements Parcelable {
public int left;
public int top;
public int right;
public int bottom;
//实现Parcelable.Creator的接口
public static final Parcelable.Creator<myParcelable> CREATOR = new
Parcelable.Creator<myParcelable>() {
public myParcelable createFromParcel(Parcel in) {
return new myParcelable(in);
}
public myParcelable[] newArray(int size) {
return new myParcelable[size];
}
};
public myParcelable() {
}
private myParcelable(Parcel in) {
readFromParcel(in);
}
public void readFromParcel(Parcel in) {
left = in.readInt();
top = in.readInt();
right = in.readInt();
bottom = in.readInt();
}
//实现Parcelable接口
public void writeToParcel(Parcel out, int flags) {
out.writeInt(left);
out.writeInt(top);
out.writeInt(right);
out.writeInt(bottom);
}
public int describeContents() {
return 0;
}
import android.os.Parcel; import android.os.Parcelable; public final class myParcelable implements Parcelable { public int left; public int top; public int right; public int bottom; //实现Parcelable.Creator的接口 public static final Parcelable.Creator<myParcelable> CREATOR = new Parcelable.Creator<myParcelable>() { public myParcelable createFromParcel(Parcel in) { return new myParcelable(in); } public myParcelable[] newArray(int size) { return new myParcelable[size]; } }; public myParcelable() { } private myParcelable(Parcel in) { readFromParcel(in); } public void readFromParcel(Parcel in) { left = in.readInt(); top = in.readInt(); right = in.readInt(); bottom = in.readInt(); } //实现Parcelable接口 public void writeToParcel(Parcel out, int flags) { out.writeInt(left); out.writeInt(top); out.writeInt(right); out.writeInt(bottom); } public int describeContents() { return 0; }

在使用时导入相应的Parcelable类即可。

C++

使用C++来实现Parcelable类相比于Java实现要复杂许多,大致包含如下几个步骤。

1.定义aidl文件,如myParcelable.aidl,其内容如下:

package android.com.example;
parcelable myParcelable cpp_header “myParcelable.h”;
package android.com.example; parcelable myParcelable cpp_header “myParcelable.h”;

2.添加对应的头文件与源码文件,如myParcelable.h与myParcelable.cpp,在头文件中声明类myParcelable并使其继承android::Parcelable,覆写virtual status_t writeToParcel(Parcel* parcel)与virtual status_t readFromParcel(const Parcel* parcel),并根据自身需要实现其他的方法即可,这里给出示例代码。

myParcelable.h头文件:

//myParcelable.h
#ifndef __MY_PARCELABLE_H__
#define __MY_PARCELABLE_H__
#include <vector>
#include <utils/Errors.h>
#include <utils/String8.h>
#include <utils/String16.h>
#include <binder/Parcelable.h>
#include <binder/Parcel.h>
using namespace std;
using android::Parcel;
using android::Parcelable;
using android::String16;
using android::String8;
class myPaecelable : public Parcelable
{
public:
myPaecelable ();
myPaecelable (int32_t messageId);
~myPaecelable ();
virtual status_t writeToParcel(Parcel *parcel) const override;
virtual status_t readFromParcel(const Parcel *parcel) override;
void setMessageId(const int32_t messageId);
public:
int32_t messageId;
};
#endif
//myParcelable.h #ifndef __MY_PARCELABLE_H__ #define __MY_PARCELABLE_H__ #include <vector> #include <utils/Errors.h> #include <utils/String8.h> #include <utils/String16.h> #include <binder/Parcelable.h> #include <binder/Parcel.h> using namespace std; using android::Parcel; using android::Parcelable; using android::String16; using android::String8; class myPaecelable : public Parcelable { public: myPaecelable (); myPaecelable (int32_t messageId); ~myPaecelable (); virtual status_t writeToParcel(Parcel *parcel) const override; virtual status_t readFromParcel(const Parcel *parcel) override; void setMessageId(const int32_t messageId); public: int32_t messageId; }; #endif

myParcelable.cpp源文件

include "myParcelable.h"
myPaecelable ::myPaecelable () : messageId(0)
{
}
myPaecelable ::~myPaecelable ()
{
}
myPaecelable ::myPaecelable (int32_t messageId) : messageId(messageId)
{
}
status_t myPaecelable ::writeToParcel(Parcel *parcel) const
{
if (parcel == nullptr)
{
LOGE("[myPaecelable ] parcel == nullptr");
return BAD_VALUE;
}
status_t res = OK;
res = parcel->writeInt32(messageId);
if (res != OK)
{
LOGE("[myPaecelable ] writeInt32 failed, ret:[%d]", res);
return res;
}
return OK;
}
status_t myPaecelable ::readFromParcel(const Parcel *parcel)
{
if (parcel == nullptr)
{
LOGE("[myPaecelable] parcel == nullptr");
return BAD_VALUE;
}
status_t res = OK;
res = parcel->readInt32(&messageId);
if (res != OK)
{
LOGE("[myPaecelable] readInt32 failed, ret:[%d]", res);
return res;
}
return OK;
}
void myPaecelable ::setMessageId(const int32_t messageId)
{
this->messageId = messageId;
}
include "myParcelable.h" myPaecelable ::myPaecelable () : messageId(0) { } myPaecelable ::~myPaecelable () { } myPaecelable ::myPaecelable (int32_t messageId) : messageId(messageId) { } status_t myPaecelable ::writeToParcel(Parcel *parcel) const { if (parcel == nullptr) { LOGE("[myPaecelable ] parcel == nullptr"); return BAD_VALUE; } status_t res = OK; res = parcel->writeInt32(messageId); if (res != OK) { LOGE("[myPaecelable ] writeInt32 failed, ret:[%d]", res); return res; } return OK; } status_t myPaecelable ::readFromParcel(const Parcel *parcel) { if (parcel == nullptr) { LOGE("[myPaecelable] parcel == nullptr"); return BAD_VALUE; } status_t res = OK; res = parcel->readInt32(&messageId); if (res != OK) { LOGE("[myPaecelable] readInt32 failed, ret:[%d]", res); return res; } return OK; } void myPaecelable ::setMessageId(const int32_t messageId) { this->messageId = messageId; }

在使用时导入相应的头文件即可。

Happy
Happy
100 %
Sad
Sad
0 %
Excited
Excited
0 %
Sleepy
Sleepy
0 %
Angry
Angry
0 %
Surprise
Surprise
0 %
FranzKafka95
FranzKafka95

极客,文学爱好者。如果你也喜欢我,那你大可不必害羞。

文章: 91

留下评论

您的电子邮箱地址不会被公开。 必填项已用*标注

zh_CNCN