我一直在向Parcelable
写Parcel
s而不关注flags字段,这是方法签名中的一个参数,它运行良好但是我遇到了一个我无法实现的实现更长时间忽略它们:
public static <K extends Parcelable, V extends Parcelable> void write(Parcel dest,
Map<K, V> map, int flags) {
if (map == null) {
dest.writeInt(-1);
} else {
Set<Map.Entry<K, V>> entrySet = map.entrySet();
dest.writeInt(entrySet.size());
for (Map.Entry<K, V> entry : entrySet) {
dest.writeParcelable(entry.getKey(), flags);
dest.writeParcelable(entry.getValue(), flags);
}
}
}
这是我写的Map
到 Parcelable
实用程序,我想知道是否应该将标志传递给 Key < / em>以及写入它们时的 Value 或者应该为 Key 传递0,为{em> Value 传递flags
。
我阅读了docs中标志的定义:
PARCELABLE_WRITE_RETURN_VALUE
在API级别1中添加
int PARCELABLE_WRITE_RETURN_VALUE
与
writeToParcel(Parcel, int)
一起使用的标志:对象是 write是一个返回值,也就是函数的结果 “Parcelable someFunction()”,“void someFunction(out Parcelable)”,或“void someFunction(inout Parcelable)”。一些 实现可能希望在此时释放资源。常数值:1(0x00000001)
但我无法理解它。任何人都可以用简单的术语解释一下Parcelable
旗是什么以及它应该如何使用?
答案 0 :(得分:5)
唯一当前存在的标志(PARCELABLE_WRITE_RETURN_VALUE
)旨在用于AIDL接口。它应该暗示某些类型的Parcelable对象,它们是从IPC方法返回的,因此可以释放它们的相关资源。在Fot实例中,ContentProvider内部包含AIDL方法,如下所示:
ParcelFileDescriptor openFile(String path, int flags);
当您在自定义ContentProvider中覆盖openFile
时,您的方法会返回 open ParcelFileDescriptor ...您自己并未关闭它,并且在进程间传输期间也不会自动关闭(传递)进程之间的描述符并不意味着在Linux中关闭它们。但描述符没有泄露!而是在写入Parcel时使用ParcelFileDescriptor closes itself:
@Override
public void writeToParcel(Parcel out, int flags) {
if (mWrapped != null) {
try {
mWrapped.writeToParcel(out, flags);
} finally {
releaseResources();
}
} else {
if (mCommFd != null) {
out.writeInt(1);
out.writeFileDescriptor(mFd);
out.writeFileDescriptor(mCommFd);
} else {
out.writeInt(0);
out.writeFileDescriptor(mFd);
}
if ((flags & PARCELABLE_WRITE_RETURN_VALUE) != 0 && !mClosed) {
// Not a real close, so emit no status
closeWithStatus(Status.SILENCE, null);
}
}
}
由于ParcelFileDescriptor只是普通的类,使用Binder / Parcel的工具在进程之间传递FileDescriptor,你可以想象存在类似的类,它们保存在本机资源(内存,文件描述符)上,并在从openFile返回时有条件地释放它们 - 喜欢的方法。
同样,其他标志可以用于在Parcelable matryoshka中传播类似的条件行为。不幸的是,Android开发人员没有为引入这样的自定义标志定义合理的规则(与IBinder#FIRST_CALL_TRANSACTION
和IBinder#LAST_CALL_TRANSACTION
不同),并且AIDL在Android内部的实践中并未广泛使用,所以我不知道任何这种旗帜的例子。
答案 1 :(得分:0)
您只能提供零或一个标志。
你有一个void方法,所以你没有从函数中返回一个Parcelable,也没有像Parcelable那样的参数,正如文档所说,因此标志应该为零。