What is the use of flags in Parcelable?

一笑奈何 提交于 2019-12-05 00:20:19

The only currently existing flag (PARCELABLE_WRITE_RETURN_VALUE) is intended for use in AIDL interfaces. It is supposed to hint certain kinds of Parcelable objects, that they are being returned from IPC method, so their associated resources can be released. Fot instance, ContentProvider internally contains AIDL method like this:

ParcelFileDescriptor openFile(String path, int flags);

When you override openFile in a custom ContentProvider, your method returns an open ParcelFileDescriptor… You aren't closing it yourself, and it is not automatically closed during interprocess transfer either (passing descriptors between processes does not imply closing them in Linux). But the descriptor is not leaked! Instead the ParcelFileDescriptor closes itself when written to Parcel:

@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);
        }
    }
}

Since ParcelFileDescriptor is just ordinary class, using facilities of Binder/Parcel to pass FileDescriptor between processes, you can imagine existence of similar classes, that hold onto native resources (memory, file descriptors) and conditionally release them when returned from openFile-like methods.

Likewise, other flags could be used to propagate similar conditional behavior deeply down Parcelable matryoshka. Unfortunately, Android developers haven't defined reasonable rules for introducing such custom flags (unlike e.g. IBinder#FIRST_CALL_TRANSACTION and IBinder#LAST_CALL_TRANSACTION), and AIDL is not widely used in practice outside of Android internals, so I am not aware of any examples of such flags.

You can only provide flag zero or one.

You have a void method, so you're not returning a Parcelable from a function nor do you have a parameter that's Parcelable, as the documentation says, therefore the flag should be zero.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!