2012-01-05 12 views
23
// Application ... 
Intent i = new Intent(); 
i.putExtra(EXTRA_FILE_UPLOAD_URIS, mGalleryAdapter.getItems()); 

Uri[] getItems() { return mItems; } 

// Service ... 
intent.getParcelableArrayExtra(EXTRA_FILE_UPLOAD_URIS); //works, returns Parcelable[] 
Uri[] uris = (Uri[])intent.getParcelableArrayExtra(EXTRA_FILE_UPLOAD_URIS); 
// ... Breaks with ClassCastException 

नहीं मिलता क्यों Uri[] को तोड़ने के लिए कलाकारों, जब UriParcelable है?मैं क्यों इस ClassCastException होता

+0

स्टैकट्रैक पोस्ट करें। –

+0

क्या 'उरी' को 'पार्सेलबल' या रिवर्स से प्राप्त होता है? – fge

+0

उरी पार्ससेलबल –

उत्तर

19

दुर्भाग्य से Java में सरणी के लिए ऐसा करने का कोई तरीका नहीं है। आपको अपनी सरणी को फिर से चालू करना होगा और प्रत्येक ऑब्जेक्ट को व्यक्तिगत रूप से डालना होगा।

इस प्रकार का कारण सुरक्षा है, JVM बस यह सुनिश्चित नहीं कर सकता है कि आपकी सरणी की सामग्री उरी को जा सकती है, बिना उन्हें दोहराए बिना, यही कारण है कि आपको उन्हें फिर से भरना होगा और उन्हें व्यक्तिगत रूप से डालना होगा।

असल में क्योंकि Parcelable अन्य ऑब्जेक्ट्स द्वारा विरासत में प्राप्त किया जा सकता है, इस बात की कोई गारंटी नहीं है कि ऐरे में केवल Uri ऑब्जेक्ट्स हैं। हालांकि एक सुपरटेप को कास्टिंग तब से काम करेगा जब से सुरक्षा की तरह ठीक रहेगा। परिदृश्य के रूप में ऊपर कुछ है

class Parent { } 

class MaleParent extends Parent { } 

class FemaleParent extends Parent { } 

तो निम्नलिखित कार्यावधि में असफल हो जायेगी:

+0

लागू करता है मैंने सोचा (चूंकि यह सी # में है) इसलिए मैंने जावा सरणी कॉन्वर्सिस देखा और ऐसा लगता है (और प्रकार की सुरक्षा में छेद होना)। क्या मेरे संदर्भ वर्तमान जेवीएम से पुरानी हैं? : http://www.angelikalanger.com/Articles/Papers/JavaGenerics/ArraysInJavaGenerics.htm, http://c2.com/cgi/wiki?JavaArraysBreakTypeSafety –

+1

मुझे लगता है कि प्रकार की सुरक्षा जेनेरिक से संबंधित है, जो संकलन के समय तक सीमित है । Arrays जेनरेट नहीं कर रहे हैं। वे संदर्भ हैं और आप कास्टिंग कर सकते हैं। –

+0

सही है, लेकिन पार्सेलबल [] पहली जगह में एक नया उरी [] था ... इसलिए यह सिर्फ तब भी होना चाहिए जब उरी एक पार्सेलबल है लेकिन उरी [] एक पार्सलबल नहीं है [] ... –

0

मुझे लगता है कि क्या हो रहा है कुछ इस प्रकार है

Parent[] parents = new FemaleParent[]{}; 
MaleParent[] maleParents = (MaleParent[]) parents; 

कुछ इस प्रकार अपवाद बढ़ा नहीं है :

Parent[] parents = new MaleParent[]{}; 
MaleParent[] maleParents = (MaleParent[]) parents; 
+0

क्यों करता है इतने सारे माता-पिता? – Sayka

26

इस विधि का उपयोग करें, यह मेरे लिए काम करता है।

Parcelable[] ps = getIntent().getParcelableArrayExtra(); 
Uri[] uri = new Uri[ps.length]; 
System.arraycopy(ps, 0, uri, 0, ps.length); 
9

Arrays में polymorphic व्यवहार है - केवल सामान्य प्रकार नहीं हैं।

यही है, अगर UriParcelable तो लागू करता

आप कह सकते हैं:

Parcelable[] pa = new Uri[size]; 
Uri[] ua = (Uri[]) pa; 

आप नहीं कह सकते हैं:

List<Parcelable> pl = new ArrayList<Uri>(); 

जैसा कि आप देख हम Uri[] को वापस pa डाली कर सकते हैं। तो समस्या क्या है? यह ClassCastException तब होता है जब आपका ऐप मारा जाता है और बाद में सहेजा गया सरणी फिर से बनाई जाती है। जब इसे रनटाइम बनाया जाता है तो पता नहीं चलता कि किस प्रकार की सरणी (Uri[]) ऐसा इसलिए था कि यह सिर्फ Parcelable[] बनाता है और इसमें तत्व डालता है। इसलिए ClassCastException जब आप इसे Uri[] पर डालने का प्रयास करते हैं।

ध्यान दें कि जब प्रक्रिया को नहीं मारा जाता है और मूल रूप से निर्मित सरणी (Uri[]) राज्य को सहेजने/पुनर्स्थापित करने के बीच अपवाद (सैद्धांतिक रूप से) नहीं होता है। जब आप अभिविन्यास बदलते हैं।

मैं बस यह स्पष्ट करना चाहता था कि ऐसा क्यों हुआ। यदि आप समाधान चाहते हैं तो @ सोलो एक सभ्य प्रदान करता है।

चीयर्स

+1

यह सही उत्तर है। जब मैंने सेवा प्रबंधक के बंडल से खाता [] में पार्ससेल योग्य [] को कास्ट करने का प्रयास किया तो मैंने क्लासकास्ट अपवाद को फिर से दिखने पर ठोकर खाई। फ़ोन कॉल के बाद यह बहुत ही कम हो गया, और अंत में - यहां अपराधी है! – user1643723

संबंधित मुद्दे