What is the use of flags in Parcelable?

I wrote Parcelable to Parcel without any attention to the flag field, which is a parameter in the method signature, and it worked fine, but I came across an implementation where I can no longer ignore them: / p>

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

This is the Map to / from Parcelable that I wrote, and I wonder if flags should be passed for both keys and for the value when they are written, or should pass 0 for Key and flags for the value.

I read the definition that the flag is in docs :

PARCELABLE_WRITE_RETURN_VALUE

added to API level 1

 int PARCELABLE_WRITE_RETURN_VALUE 

Flag for use with writeToParcel(Parcel, int) : the object being written is the return value, that is, the result of a function such as "Parcelable someFunction ()" , "void someFunction (out Parcelable)" or "void someFunction (inout Parcelable)" . Some implementations may want to free resources at this point.

Constant value: 1 (0x00000001)

But I can’t figure it out. Can someone just explain what the Parcelable flag Parcelable and how to use it?

+5
source share
2 answers

The only current flag ( PARCELABLE_WRITE_RETURN_VALUE ) is intended for use in AIDL interfaces. It is assumed that it hints at certain types of Parcelable objects that they are returning from the IPC method, so their associated resources can be freed. Fot, ContentProvider internally contains the AIDL method, for example:

 ParcelFileDescriptor openFile(String path, int flags); 

When you override openFile in a custom ContentProvider, your method returns the open ParcelFileDescriptor ... you do not close it yourself, and it does not close automatically during interprocess transfer (passing descriptors between processes does not mean they are closed in Linux). But the handle did not leak! Instead, ParcelFileDescriptor closes itself when writing in 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 a regular class, using Binder / Parcel to transfer FileDescriptor between processes, you can imagine the existence of such classes that are stored on their own resources (memory, file descriptors) and conditionally free them when they return from openFile-like methods.

Similarly, other flags can be used to spread similar conditional behavior deep down. Gradual nesting doll. Unfortunately, the Android developers did not define reasonable rules for introducing such custom flags (unlike, for example, IBinder#FIRST_CALL_TRANSACTION and IBinder#LAST_CALL_TRANSACTION ), and AIDL is not widely used in practice outside the internal Android systems, so I do not know any examples of such flags .

+4
source

You can specify only a flag or a single flag.

You have a void method, so you are not returning Parcelable from the function, and you do not have the Parcelable parameter, as indicated in the documentation, so the flag must be zero.

0
source

Source: https://habr.com/ru/post/1268254/


All Articles