Parcelable中标志的用途是什么?

时间:2017-05-26 13:45:43

标签: android parcelable flags parcel

我一直在向ParcelableParcel 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旗是什么以及它应该如何使用?

2 个答案:

答案 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_TRANSACTIONIBinder#LAST_CALL_TRANSACTION不同),并且AIDL在Android内部的实践中并未广泛使用,所以我不知道任何这种旗帜的例子。

答案 1 :(得分:0)

您只能提供零或一个标志。

你有一个void方法,所以你没有从函数中返回一个Parcelable,也没有像Parcelable那样的参数,正如文档所说,因此标志应该为零。