Parcelable где / когда используется describeContents ()?

94

Кто-нибудь знает, где / когда вызывается этот метод Parcelable ?

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

Это должно быть преодолено. Но стоит ли делать с ним что-нибудь полезное?

Коди
источник
Вроде ни у кого нет идей ..? : - /
cody

Ответы:

183

В Parcelableвызове определена константа, CONTENTS_FILE_DESCRIPTORкоторая предназначена для использования describeContents()для создания возвращаемого значения битовой маски.

Описание CONTENTS_FILE_DESCRIPTORв API ref :

Битовые маски для использования с описаниемContents (): каждый бит представляет собой объект, который считается потенциально важным при упорядочивании.

Что на самом деле означает: Если вам нужно поместить FileDescriptorобъект в Parcelable вы должны / необходимо указать в CONTENTS_FILE_DESCRIPTORкачестве возвращаемого значения describeContents (), то есть по « специальному объекту » (в describeContents()описании iS) они на самом деле означают: FileDescriptor.

Вся эта функциональность Parcelable выглядит незавершенной (читай: имеет плохой дизайн). В документации есть еще одна странность:

Классы, реализующие интерфейс Parcelable, также должны иметь статическое поле CREATOR, которое является объектом, реализующим интерфейс Parcelable.Creator.

Реализуете множественное наследование по правилам, определенным в удобочитаемой форме? :-)

Похоже, программист на C ++ спроектировал Parceableи в какой-то момент понял: черт возьми, в Java нет множественного наследования ... :-)

Огнян
источник
3
Спасибо за подробное объяснение. Я нашел ваш ответ после того, как разочаровался в этом руководстве, в котором утверждалось, что он describeContents()должен возвращать 0, когда «в нем нет ничего особенного» . Что на самом деле ничего не объясняет. Ваше объяснение намного яснее!
WebViewer
1
@LeoLink android.os.ParcelFileDescriptor
Огнян
8
Дело не в множественном наследовании. Вы не можете определить статический метод в интерфейсе Java, кроме версии, используемой в Android, поэтому это поле CREATOR.
Алекс Н.
3
@androiddeveloper Я думаю, что его нельзя использовать в «нормальной» разработке приложений. Похоже, что он используется только собственными методами для передачи информации между процессами. Пожалуйста, взгляните на InputChannel.java (класс, описывающий комментарий) и android_os_Parcel.cpp
Огнян
2
Единственное использование CONTENTS_FILE_DESCRIPTOR( на самом деле, hasFileDescriptors()метод) , что я смог найти в исходном коде Android, чтобы бросить IllegalArgumentExceptionв ActivityManagerServiceс сообщением: «File дескрипторы передаются в Bundle / Намерение опции /» до «отказаться от возможных просочились дескрипторов файлов» . Насколько я понимаю, это из соображений безопасности (с использованием разрешения другого приложения). Поправьте меня если я ошибаюсь.
Slav
8

Возможны только два значения: 0 или CONTENTS_FILE_DESCRIPTOR.

если вы сериализуете POLO, это значение всегда должно быть 0, CONTENTS_FILE_DESCRIPTOR зарезервирован для ParcelFileDescriptor , который может сериализовать файловый дескриптор (FD) в системе * unix.

лучник хан
источник
1

Из фреймворка 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 (). И пакет будет выполнять итерацию всех данных в mMap (hashMap) или mParcelledData (Parcel). Мы разберемся с намерением. HasFileDescriptors () просто обертывает Parcel / Parcelable describeContents ().

Хотя, возможно, это единственное использование для describeContents (): оно используется для фильтрации FileDescriptor из Intent pass ...

Аллан
источник