103

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?

hata
  • 11,633
  • 6
  • 46
  • 69
cody
  • 6,389
  • 15
  • 52
  • 77

3 Answers3

192

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

Mithun
  • 2,075
  • 3
  • 19
  • 26
Ognyan
  • 13,452
  • 5
  • 64
  • 82
  • 3
    Thanks for this detailed explanation. I found your answer after being frustrated by [this tutorial](http://www.app-solut.com/blog/2011/05/using-self-defined-parcelable-objects-during-an-android-aidl-rpc-ipc-call/) 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! – WebViewer Jan 22 '14 at 22:52
  • what do you mean by "put FileDescriptor object into Parcelable", I don't get it because FileDescriptor doesn't implement Parcelable interface. – Leo Oct 19 '14 at 15:43
  • 1
    @LeoLink android.os.ParcelFileDescriptor – Ognyan Oct 21 '14 at 10:34
  • 9
    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. – Aleks N. Oct 27 '14 at 16:20
  • 1
    @Ogre_BGR I still don't get it. Maybe can you show an example code of when it could be useful? – android developer Jan 27 '15 at 00:43
  • 3
    @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](http://androidxref.com/source/xref/frameworks/base/core/java/android/view/InputChannel.java) (class describing comment) and [android_os_Parcel.cpp](http://androidxref.com/4.2_r1/xref/frameworks/base/core/jni/android_os_Parcel.cpp#560) – Ognyan Jan 27 '15 at 11:31
  • @Ogre_BGR This doesn't give me much clues as to what they did there. How odd. – android developer Jan 27 '15 at 13:14
  • @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 (?)... – Ognyan Jan 27 '15 at 15:25
  • @Ogre_BGR So the answer is that it's probably a leftover that nobody uses? – android developer Jan 27 '15 at 17:01
  • Can you give some example? – Malwinder Singh May 28 '15 at 10:24
  • 2
    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. – Slav Aug 29 '17 at 13:21
  • @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 Aug 29 '17 at 13:49
  • 1
    @Slav also here is a list where `CONTENT_FILE_DESCRIPTOR` is used: http://androidxref.com/source/search?q=return+Parcelable.CONTENTS_FILE_DESCRIPTOR%3B&defs=&refs=&path=&hist=&project=abi&project=bionic&project=bootable&project=build&project=cts&project=dalvik&project=development&project=device&project=docs&project=external&project=frameworks&project=gdk&project=hardware&project=libcore&project=libnativehelper&project=ndk&project=packages&project=pdk&project=prebuilts&project=sdk&project=system&project=tools – Ognyan Aug 29 '17 at 13:52
  • "This whole Parcelable functionality looks unfinished" - Everything about Android looks unfinished. – Ash Dec 17 '19 at 02:29
10

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.

Shalom Craimer
  • 20,659
  • 8
  • 70
  • 106
bowman han
  • 1,097
  • 15
  • 25
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...

allan
  • 31
  • 2