สามารถจัดเก็บได้ที่ไหน / เมื่อใดที่ใช้ DescriptionContents ()?


94

ไม่มีใครรู้ว่าวิธีนี้เรียกว่าParcelableที่ไหน / เมื่อไหร่?

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

จะต้องมีการลบล้าง แต่ฉันควรทำสิ่งที่เป็นประโยชน์กับมันไหม


ดูเหมือนไม่มีใครคิด .. ? : - /
cody

คำตอบ:


183

มีการกำหนดค่าคงที่ในการParcelableเรียกCONTENTS_FILE_DESCRIPTORซึ่งมีไว้เพื่อใช้ในdescribeContents()การสร้างค่าส่งคืน bitmask

คำอธิบายCONTENTS_FILE_DESCRIPTORในการอ้างอิง APIคือ:

มาสก์บิตสำหรับใช้กับ descriptionContents (): แต่ละบิตแสดงถึงชนิดของวัตถุที่พิจารณาว่ามีความสำคัญพิเศษที่อาจเกิดขึ้นเมื่อมีการมาร์แชล

ซึ่งหมายความว่าจริงๆ: ถ้าคุณต้องการที่จะนำFileDescriptorวัตถุเข้า Parcelable คุณควร / ต้องระบุCONTENTS_FILE_DESCRIPTORเป็นค่าตอบแทนของ describeContents () คือด้วย " วัตถุพิเศษ " (ในdescribeContents()คำอธิบาย 's) FileDescriptorพวกเขาหมายถึงจริงๆ:

ฟังก์ชันParcelableทั้งหมดนี้ดูเหมือนยังไม่เสร็จสมบูรณ์ (อ่าน: มีการออกแบบที่ไม่ดี) มีสิ่งแปลก ๆ อีกอย่างในเอกสาร:

คลาสที่ใช้อินเทอร์เฟซ Parcelable ต้องมีฟิลด์สแตติกที่เรียกว่า CREATOR ซึ่งเป็นอ็อบเจ็กต์ที่ใช้อินเทอร์เฟซ Parcelable.Creator

การดำเนินการสืบทอดหลาย ๆ กฎที่กำหนดไว้ในรูปแบบที่มนุษย์อ่านได้? :-)

ดูเหมือนว่าโปรแกรมเมอร์ C ++ ได้รับการออกแบบParceableและเมื่อถึงจุดหนึ่งเขาก็ตระหนักว่า: โอ้ยี้ไม่มีการสืบทอดหลายรายการใน Java ... :-)


3
ขอบคุณสำหรับคำอธิบายโดยละเอียดนี้ ผมพบว่าคำตอบของคุณหลังจากที่ถูกผิดหวังโดยการกวดวิชานี้อ้างว่าdescribeContents()ควรกลับ 0 เมื่อใดก็ตามที่"มีอะไรพิเศษเกี่ยวกับเรื่องนี้" ซึ่งไม่ได้อธิบายอะไรจริงๆ. คำอธิบายของคุณชัดเจนกว่ามาก!
WebViewer

1
@LeoLink android.os.ParcelFileDescriptor
Ognyan

8
ไม่เกี่ยวกับการสืบทอดหลาย ๆ คุณไม่สามารถกำหนดวิธีการแบบคงที่ในอินเทอร์เฟซ Java ไม่ใช่ในเวอร์ชันที่ใช้ใน Android ดังนั้นฟิลด์ CREATOR นี้
Aleks N.

3
@androiddeveloper ฉันคิดว่ามันไม่สามารถใช้ในการพัฒนาแอพ "ปกติ" ได้ ดูเหมือนว่าจะถูกใช้โดยวิธีดั้งเดิมเท่านั้นเพื่อส่งผ่านข้อมูลระหว่างกระบวนการ โปรดดูที่InputChannel.java (คลาสอธิบายความคิดเห็น) และandroid_os_Parcel.cpp
Ognyan

2
การใช้งานเพียงคนเดียวCONTENTS_FILE_DESCRIPTOR(ที่จริงhasFileDescriptors()วิธีการ) ที่ฉันก็สามารถที่จะหาได้ใน Android ซอร์สโค้ดคือการขว้างปาIllegalArgumentExceptionในActivityManagerServiceกับข้อความ: "อธิบายไฟล์ผ่านใน Bundle / ตัวเลือก / เจตนา"ที่จะ"ปฏิเสธเป็นไปได้อธิบายไฟล์รั่วไหลออกมา" ความเข้าใจของฉันคือเหตุผลด้านความปลอดภัย (โดยใช้การอนุญาตของแอปอื่น) ช่วยแก้ให้ด้วยนะถ้าฉันผิด.
Slav

8

มีเพียงสองค่าที่เป็นไปได้คือ 0 หรือ CONTENTS_FILE_DESCRIPTOR

หากคุณกำลังต่ออนุกรม POLO ค่านี้ควรเป็น 0 เสมอ CONTENTS_FILE_DESCRIPTOR สงวนไว้สำหรับParcelFileDescriptorซึ่งสามารถทำให้อนุกรมของ File Descriptor (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 / ParcelablecribContents ()

ในขณะที่นี่อาจเป็นเพียงการใช้งานสำหรับ descriptionContents (): ใช้เพื่อกรอง FileDescriptor จาก Intent pass ...

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.