Android 旗帜在包裹中有什么用途?

Android 旗帜在包裹中有什么用途?,android,parcelable,flags,parcel,Android,Parcelable,Flags,Parcel,我一直在将Parcelables写入Parcel,但没有关注flags字段,它是方法签名中的一个参数,工作正常,但我遇到了一个无法再忽略它们的实现: public static <K extends Parcelable, V extends Parcelable> void write(Parcel dest, Map<K, V> map, int flags) {

我一直在将
Parcelable
s写入
Parcel
,但没有关注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);
            }
        }
    }
writeToParcel(Parcel,int)
一起使用的标志:正在
Write是一个返回值,它是函数的结果,例如 “可打包的someFunction()”“作废someFunction(可打包外)”,或“作废someFunction(可打包外)”。一些 此时,实现可能希望释放资源

常量值:1(0x00000001)


但我无法理解它。有谁能简单地解释一下什么是
可包裹的
标志以及应该如何使用它吗?

您只能提供零或一个标志


你有一个void方法,所以你没有从函数返回一个Parcelable,也没有一个Parcelable参数,正如文档所说,因此标志应该是零

当前唯一存在的标志(
PARCELABLE\u WRITE\u RETURN\u VALUE
)用于接口。它应该提示某些类型的可包裹对象,它们是从IPC方法返回的,因此可以释放它们的相关资源。在Fot实例中,ContentProvider内部包含如下AIDL方法:

ParcelFileDescriptor openFile(String path, int flags);
在自定义ContentProvider中重写
openFile
时,您的方法将返回一个打开的ParcelFileDescriptor…您自己并没有关闭它,并且在进程间传输期间它也不会自动关闭(在进程之间传递描述符并不意味着在Linux中关闭它们)。但是描述符没有泄漏!而是在写入地块时使用ParcelFileDescriptor:

@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的方法返回时有条件地释放它们


同样,其他标志也可用于将类似的条件行为传播到可包裹的matryoshka。不幸的是,Android开发人员没有定义引入此类定制标志的合理规则(不同于例如
IBinder#FIRST#u CALL_TRANSACTION
IBinder#LAST#u CALL_TRANSACTION
),而且AIDL在Android内部之外的实践中没有广泛使用,因此我不知道此类标志的任何示例

“一个返回值,即一个函数的结果”是相当自我的explanatory@cricket_007:我有一个void方法??但那是一个静态方法?这跟什么有关系?如果你引用了方法entry.getKey(),那么它确实返回了一个Parcelable。标志不应该是1吗?
void write
是你的方法,
entry.getKey()
是在映射界面中定义的,我不明白您的观点您只有两个选项,那么在发布问题之前您尝试了多少选项?好的,告诉我我是否理解正确。open()方法会导致IPC和另一侧(另一个进程),将创建一个FileDescriptor并最终返回给我们,因为FileDescriptor可能已在该端打开,所以在将其发送给我们之前,检查将关闭。此外,在通过IPC调用发送之前关闭资源是一个非常特殊的情况,我可能只需要在IPC过程中查找它。@Pill\u虚构是的,您完全了解了另外,这个答案只是大致正确,因为描述符实际上并没有“发送前关闭”-它是复制的(在
writeFileDescriptor
中),原始的是“关闭的”(不完全正确,因为描述符是引用计数的),然后复制的是真正关闭的(可能是在传输过程中,与我之前的说法相反,描述符在传输过程中不会关闭)。所有这些疯狂都隐藏在ParcelFileDescriptor抽象背后,使其看起来像“发送前关闭”“。他们在想什么…@plup_fiction TL;DR:不要不小心在东西中存储文件描述符,否则Dianne Hackborn会来杀了你的狗。有一个专门的方法(确定包裹中是否包含文件描述符)。
@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);
        }
    }
}