Parcelable where/when is describeContents() used?

22,524

Solution 1

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... :-)

Solution 2

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.

Solution 3

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...

Share:
22,524

Related videos on Youtube

cody
Author by

cody

Updated on November 04, 2020

Comments

  • cody
    cody over 3 years

    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?

    • cody
      cody over 13 years
      It seems no one has an idea ..? :-/
  • WebViewer
    WebViewer over 10 years
    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!
  • Leo
    Leo over 9 years
    what do you mean by "put FileDescriptor object into Parcelable", I don't get it because FileDescriptor doesn't implement Parcelable interface.
  • Ognyan
    Ognyan over 9 years
    @LeoLink android.os.ParcelFileDescriptor
  • Aleks N.
    Aleks N. over 9 years
    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.
  • android developer
    android developer over 9 years
    @Ogre_BGR I still don't get it. Maybe can you show an example code of when it could be useful?
  • Ognyan
    Ognyan over 9 years
    @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.cpp
  • android developer
    android developer over 9 years
    @Ogre_BGR This doesn't give me much clues as to what they did there. How odd.
  • Ognyan
    Ognyan over 9 years
    @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 (?)...
  • android developer
    android developer over 9 years
    @Ogre_BGR So the answer is that it's probably a leftover that nobody uses?
  • Malwinder Singh
    Malwinder Singh about 9 years
    Can you give some example?
  • Slav
    Slav almost 7 years
    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.
  • Ognyan
    Ognyan almost 7 years
    @Slav 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.
  • Ognyan
    Ognyan almost 7 years
    @Slav also here is a list where CONTENT_FILE_DESCRIPTOR is used: androidxref.com/source/…
  • Ash
    Ash over 4 years
    "This whole Parcelable functionality looks unfinished" - Everything about Android looks unfinished.