Parcelable何时何地使用describeContents()方法?

104

有人知道在何时何处会调用这个Parcelable的方法吗?

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

这个方法必须被覆盖(overriden),但我是否应该考虑对其进行一些有用的操作呢?


似乎没有人有想法..? :-/ - cody
3个回答

193
Parcelable中定义了一个常量CONTENTS_FILE_DESCRIPTOR,意味着用于describeContents()以创建位掩码返回值。
在API文档中描述CONTENTS_FILE_DESCRIPTOR是:每个位表示被视为具有潜在特殊意义的对象种类的位掩码,这实际上意味着:如果需要将FileDescriptor对象放入可包含的对象中,则应该/必须将CONTENTS_FILE_DESCRIPTOR指定为describeContents()的返回值。也就是说,“特殊对象”(在describeContents()的说明中)实际上指的是:FileDescriptor
整个Parcelable功能看起来未完成(即:设计不良)。文档中还有另一件奇怪的事情:实现Parcelable接口的类还必须有一个名为CREATOR的静态字段,它是实现Parcelable.Creator接口的对象。
通过以可读形式定义的规则实现多重继承?:-)似乎像C++程序员设计了Parceable并在某个时候意识到:哦,该死,在Java中没有多重继承... :-)

3
谢谢您提供详细的解释。我在受到 这篇教程 的困扰后找到了您的答案,该教程声称当一个对象“没有任何特殊之处”时,describeContents() 应该返回 0。但是这并没有解释任何问题。您的解释更加清晰易懂! - WebViewer
9
这不是关于多重继承的问题。在Java接口中,您无法定义静态方法,尤其是在Android中使用的版本中,因此需要使用CREATOR字段。 - Aleks N.
3
我认为它不适用于“普通”应用程序开发。看起来它只被本地方法用于在进程间传递信息。请参阅 InputChannel.java(描述注释的类)和 android_os_Parcel.cpp - Ognyan
2
在Android源代码中,我能找到的CONTENTS_FILE_DESCRIPTOR(实际上是hasFileDescriptors()方法)唯一的用途是在ActivityManagerService中抛出IllegalArgumentException异常,并显示消息:“在Bundle/Intent/options中传递文件描述符”以“拒绝可能的泄漏文件描述符”。我的理解是出于安全原因(使用另一个应用程序的权限)。如果我理解有误,请纠正我。 - Slav
显示剩余9条评论

10

只有两种可能的值,0或CONTENTS_FILE_DESCRIPTOR。

如果您正在序列化POLO,则此值应始终为0,CONTENTS_FILE_DESCRIPTOR保留用于ParcelFileDescriptor,它可以在*unix系统中序列化文件描述符(FD)。


2

从Android框架来看,唯一的使用发生在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()方法来自Bundle.java中的hasFileDescriptors()方法。 而bundle将迭代mMap(hashMap)或mParcelledData(Parcel)中的所有数据。 我们可以发现intent.hasFileDescriptors()只是包装了Parcel/Parcelable的describeContents()方法。

然而,也许这是describeContents()方法唯一的用途: 它用于从Intent传递中过滤FileDescriptor...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接