Parcelable where/when is describeContents() used?
Asked Answered
D

3

105

Does anyone know where/when this method of a Parcelable is called?

@Override
public int describeContents() {
    return 0;
}

It has to be overriden. But should I consider doing something useful with it?

Diacaustic answered 2/11, 2010 at 10:53 Comment(1)
It seems no one has an idea ..? :-/Diacaustic
H
194

There is a constant defined in Parcelable called CONTENTS_FILE_DESCRIPTOR which is meant to be used in describeContents() to create bitmask return value.

Description for CONTENTS_FILE_DESCRIPTOR in the API ref is:

Bit masks for use with describeContents(): each bit represents a kind of object considered to have potential special significance when marshalled.

Which really means: If you need to put FileDescriptor object into Parcelable you should/must specify CONTENTS_FILE_DESCRIPTOR as return value of describeContents(), i.e. by "special object" (in describeContents()'s description) they really mean: FileDescriptor.

This whole Parcelable functionality looks unfinished (read: has bad design). There is one other strange thing in the docs:

Classes implementing the Parcelable interface must also have a static field called CREATOR, which is an object implementing the Parcelable.Creator interface

Implementing multiple inheritance by rules defined in human readable form? :-)

It seems like C++ programmer designed Parceable and at some point he realized: Oh, damn, there is no multiple inheritance in Java... :-)

Hahnke answered 6/2, 2011 at 17:9 Comment(14)
Thanks for this detailed explanation. I found your answer after being frustrated by this tutorial claiming that describeContents() should return 0 whenever it "has nothing special about it". Which doesn't really explain anything. Your explanation is so much clearer!Kloman
what do you mean by "put FileDescriptor object into Parcelable", I don't get it because FileDescriptor doesn't implement Parcelable interface.Unaccountable
@LeoLink android.os.ParcelFileDescriptorHahnke
It's not about multiple inheritance. You cannot define a static method in a Java interface, not in the version used in Android, hence this CREATOR field.Maiden
@Ogre_BGR I still don't get it. Maybe can you show an example code of when it could be useful?Boon
@androiddeveloper I think that it is not ment to be used in "normal" app development. It seems like it is only used by native methods in order to pass information between processes. Please take a look at InputChannel.java (class describing comment) and android_os_Parcel.cppHahnke
@Ogre_BGR This doesn't give me much clues as to what they did there. How odd.Boon
@androiddeveloper Yep... I see the sending "side", but cannot find the receiving side and how exactly is that flag interpreted. Maybe it is some legacy leftover (?)...Hahnke
@Ogre_BGR So the answer is that it's probably a leftover that nobody uses?Boon
Can you give some example?Beefwitted
The only usage of CONTENTS_FILE_DESCRIPTOR (actually, hasFileDescriptors() method) that I was able to find in Android source code, is to throwing IllegalArgumentException in ActivityManagerService with a message: "File descriptors passed in Bundle/Intent/options" to "refuse possible leaked file descriptors". My understanding is that it is for security reasons (using permission of another app). Correct me if I'm wrong.Platy
@Platy In Jelly Bean (4.2) it throws "File descriptors passed in Intent" so basically you are probably right. It is used just as precaution against passing a file descriptor in an intent when starting activity/service/etc.Hahnke
@Platy also here is a list where CONTENT_FILE_DESCRIPTOR is used: androidxref.com/source/…Hahnke
"This whole Parcelable functionality looks unfinished" - Everything about Android looks unfinished.Porism
G
12

There is only two possible value, 0 or CONTENTS_FILE_DESCRIPTOR

if you are serializing POLO, this value should always be 0, the CONTENTS_FILE_DESCRIPTOR is reserved for ParcelFileDescriptor, which could serialize a File Descriptor(FD) in *unix system.

Gannet answered 31/8, 2017 at 6:28 Comment(0)
P
2

From android framework, the only usage occurs in ActivityManagerService.java:

//ActivityManagerService.java
public int startActivityIntentSender(IApplicationThread caller,
    IntentSender intent, Intent fillInIntent, String resolvedType,
    IBinder resultTo, String resultWho, int requestCode,
    int flagsMask, int flagsValues) {
   // Refuse possible leaked file descriptors
   if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
       throw new IllegalArgumentException("File descriptors passed in Intent");
   }
   //...
}

Intent.java hasFileDescriptors() comes from Bundle.java hasFileDescriptors(). And the bundle will iterator all data in mMap(hashMap) or mParcelledData(Parcel). We will figure out intent.hasFileDescriptors() just wraps Parcel/Parcelable describeContents().

While, maybe this is the only usage for describeContents() : it use to filter FileDescriptor from Intent pass...

Poach answered 3/11, 2020 at 9:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.