पार्सलेबल इंटरफ़ेस लागू करते समय बूलियन को कैसे पढ़ें / लिखें?


404

मैं ArrayList Parcelableएक गतिविधि को कस्टम ऑब्जेक्ट की सूची में पास करने के लिए एक बनाने की कोशिश कर रहा हूं । मैं एक myObjectListवर्ग लिखना शुरू करता हूं जो विस्तार ArrayList<myObject>और कार्यान्वित करता है Parcelable

कुछ विशेषताएँ MyObjectहैं, booleanलेकिन Parcelकोई विधि नहीं है read/writeBoolean

इसे संभालने का सबसे अच्छा तरीका क्या है?


3
क्योंकि गतिविधियों के बीच गुजरने वाली वस्तु के बारे में मैंने जो कुछ भी पढ़ा है, वह अनुक्रमिक के बजाय पार्सल के उपयोग को प्राथमिकता देता है।
ग्रंक

10
@MisterSquonk आपको Serializableअंतर-गतिविधि संचार के लिए इंटरफ़ेस का उपयोग नहीं करना चाहिए । यह धीमा है।
ऑक्टेवियन ए। डामियन

1
@grunk: ठीक है, यह काफी उचित है, लेकिन जब तक Intent.putExtra (स्ट्रिंग नाम, सीरियल मूल्य) को डॉक्स में पदावनत के रूप में चिह्नित किया जाता है, मुझे इसका उपयोग जारी रखने में खुशी होगी अगर यह मेरे लिए जीवन को आसान बनाता है। सिर्फ एक विचार।
स्क्वॉन्क

3
@ ओक्टेवियन: लेकिन यह एक प्रति-केस अध्ययन पर निर्भर करता है और सापेक्ष है।
स्क्वॉन्क

2
मेरे उत्पीड़न में, Android की वास्तुकार टीम आलसी है !!! कहाँ बूलियन !!!!!!!!
Mateus

जवाबों:


942

यहाँ है कि मैं यह कैसे करूँगा ...

writeToParcel:

dest.writeByte((byte) (myBoolean ? 1 : 0));     //if myBoolean == true, byte == 1

readFromParcel:

myBoolean = in.readByte() != 0;     //myBoolean == true if byte != 0

38
Int पर बाइट का उपयोग करने का कोई कारण नहीं। बाइट कास्ट के कारण अधिक क्रिया है: dest.writeInt (myBoolean; 1: 0);
मिगेल

@SiPlus के कमेंट को इतने उथल पुथल क्यों मिले? न तो 1, न ही 0 सभी पर "लोड" है। यह बिल्कुल कोई फर्क नहीं पड़ता। और कब से जावा एक कमजोर टाइप की भाषा है?
दोपहर

13
@sotrh एक बाइट लिखने के लिए सिर्फ एक इंट लिखते हैं:/** * Write a byte value into the parcel at the current dataPosition(), * growing dataCapacity() if needed. */ public final void writeByte(byte val) { writeInt(val); }
डलास

3
@ डलास है कि प्रलेखन से? यदि ऐसा है तो मेरी टिप्पणी की अवहेलना करें। एपी के लिए असंतुष्ट लगता है कि एक फ़ंक्शन है जो कहता है writeByte, लेकिन वास्तव में एक इंट लिखता है।
सोत्र

1
@sotrh जो किसी सोर्स कोड से कॉपी-पेस्ट है। Android.os.Parcel स्रोत खोलें और अपने लिए देखें।
यारोस्लाव मायटक्लाइक

66

तुम भी लिखने के तरीके का उपयोग कर सकता है । मेरी राय में इसका सबसे सीधा समाधान है।

dst.writeValue( myBool );

बाद में आप आसानी से इसे एक साधारण कलाकार के साथ पुनः प्राप्त कर सकते हैं Boolean:

boolean myBool = (Boolean) source.readValue( null );

हुड के तहत एंड्रॉइड फ्रेमवर्क इसे पूर्णांक के रूप में संभाल लेगा:

writeInt( (Boolean) v ? 1 : 0 );

एंड्रॉइड स्रोत "हुड के नीचे" भाग दिखा रहा है (एल। 1219)। हालांकि एक छोटा सा कम कुशल (विधि कॉल और स्विच के कारण) यह विधि थोड़ा और अधिक सरल है।
डेसिम

6
यहाँ लिखा कोड संकलित नहीं होगा। readValue के लिए एक क्लास लोडर की आवश्यकता होती है लेकिन यह बूलियंस के लिए आवश्यक नहीं है। इसे "बूलियन मायबूल = (बूलियन) सोर्स.readValue (नल) पढ़ना चाहिए;" समीक्षकों को पता नहीं है कि वे क्या कर रहे हैं और इस उत्तर के लिए मेरे संपादन को अस्वीकार कर दिया है: @hemang, jeeped, DavidRR।
मिगेल

1
@ मिगुएल यह सच है, इसे ठीक कर दिया :)
ताईग

15

आप इस तरह की घोषणा करते हैं

 private boolean isSelectionRight;

लिखो

 out.writeInt(isSelectionRight ? 1 : 0);

पढ़ना

isSelectionRight  = (in.readInt() == 0) ? false : true;

बूलियन प्रकार को पार्सल का समर्थन करने वाली किसी चीज़ में बदलना होगा और इसलिए हम इसे इंट में बदल सकते हैं।


यह एक त्रुटि, असंगत प्रकारों का कारण बनता है, आवश्यक बूलियन को int मिला?
पॉल ओकेक

12

AndroidStudio (2.3 एटीएम का उपयोग करके), अपनी कक्षा पर पार्सलबल लागू करने के बाद, आप अपने माउस पॉइंटर को अपनी कक्षा के नाम पर रख सकते हैं और यह आपसे पार्सलेबल कार्यान्वयन को जोड़ने के लिए कहता है:

यहां छवि विवरण दर्ज करें

चार क्षेत्रों से, यह निम्नलिखित उत्पन्न करता है:

public class YourClass implements Parcelable{

String someString;
int someInt;
boolean someBoolean;
List<String> someList;

protected YourClass(Parcel in) {
    someString = in.readString();
    someInt = in.readInt();
    someBoolean = in.readByte() != 0;
    someList = in.createStringArrayList();
}

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(someString);
    dest.writeInt(someInt);
    dest.writeByte((byte) (someBoolean ? 1 : 0));
    dest.writeStringList(someList);
}

...

यह आसान है :)
डिनो ट्व

8

मैं आम तौर पर उन्हें एक सरणी में रखता हूं और कॉल करता हूं writeBooleanArrayऔरreadBooleanArray

यदि यह एक एकल बूलियन है जिसे आपको पैक करने की आवश्यकता है, तो आप ऐसा कर सकते हैं:

parcel.writeBooleanArray(new boolean[] {myBool});

क्या आपको कभी समस्या का सामना करना पड़ा है जब आपको कुछ बूलियन्स को पार्सल करने की आवश्यकता होती है ... मेरे पास है। क्या आप कृपया मेरी मदद कर सकते हैं> stackoverflow.com/questions/13463727/… । धन्यवाद।
रोजर एलियन


5

मैंने आपको Parcelable को लागू करने का सबसे आसान तरीका सुझाया है यदि आप Android Studio का उपयोग कर रहे हैं।

बस करने के लिए जाओ फ़ाइल-> सेटिंग्स-> प्लगइन्स-> ब्राउज रिपॉजिटरी में जाएं और पार्सलबल देखें। छवि देखें

यहां छवि विवरण दर्ज करें यह स्वचालित रूप से Parcelable बनाएगा।

और ऐसा करने के लिए एक वेबिस्ट भी है। http://www.parcelabler.com/


4

कोटलिन में लघु और सरल कार्यान्वयन समर्थन के साथ:

पार्सल में विधियाँ जोड़ें

fun Parcel.writeBoolean(flag: Boolean?) {
    when(flag) {
        true -> writeInt(1)
        false -> writeInt(0)
        else -> writeInt(-1)
    }
}

fun Parcel.readBoolean(): Boolean? {
    return when(readInt()) {
        1 -> true
        0 -> false
        else -> null
    }
}

और इसका उपयोग करें:

parcel.writeBoolean(isUserActive)

parcel.readBoolean()        // For true, false, null
parcel.readBoolean()!!      // For only true and false

@AliKazi आप समर्थन वैकल्पिक प्रकारों के साथ जावा में 1 लाइन स्टेटमेंट में ऐसा नहीं कर सकते। आपको 3 राज्यों को जारी रखना चाहिए। मुझे लगता है कि आप अशक्त के बारे में भूल जाते हैं।
पावेल शोरोखोव

@ comm1x, IDE को यह समाधान पसंद नहीं है। सुपरक्लास कंस्ट्रक्टर को बुलाए जाने से पहले "readBoolean" तक नहीं पहुंच सकता।
एडम हर्वित्ज

@ comm1x मैंने इस मुद्दे को हल किया। जोड़े गए तरीकों को काम करने के लिए साथी वस्तु के
एडम हर्वित्ज

3

आप अपने बूलियन मूल्यों को मास्किंग और शिफ्टिंग का उपयोग करके बाइट में पैक कर सकते हैं। ऐसा करने का यह सबसे कारगर तरीका होगा और शायद वही होगा जो वे आपसे करने की उम्मीद करेंगे।


+1। सच है, एक बाइट में मूल्य की बचत अधिक कुशल होगी। क्या आप मुझे अपने विचार का प्रतिनिधित्व करने के लिए मेरे प्रश्न का संपादन करने का मन करेंगे?
ऑक्टेवियन ए। डामियन

आप कर सकते हैं, लेकिन आपने जो लिखा है वह वास्तव में मेरा मतलब नहीं है। यह काम करेगा लेकिन सबसे कुशल नहीं है। आप मास्क और बूलियन बीजगणित का उपयोग करके एक बाइट में 8 बूलियन पैक कर सकते हैं
बेड़े 176

ज्यादातर मामलों में मैं आपसे सहमत हूं, हालांकि मेरे पास ऐसे मामले हैं जो समय-समय पर रेंगते हैं जहां मुझे तीन राज्यों की जरूरत है जो बूलियन काम करेंगे। जैसे कि एक वैकल्पिक हां / कोई सवाल नहीं। मुझे यह जानने की आवश्यकता है कि बुलियन को स्पष्ट रूप से निर्दिष्ट किया गया है या नहीं।
चाड गोर्शिंग

वहाँ कोई कारण नहीं है बाइट का उपयोग करते हुए, क्योंकि पार्सल की writeByte()विधि सीधे कॉल करती हैwriteInt()
यारोस्लाव Mytkalyk

3

यहां वास्तविक प्रश्न की पहचान करना कठिन है। मुझे लगता है कि Parcelableइंटरफ़ेस को लागू करते समय बूलियंस से कैसे निपटना है।

MyObject की कुछ विशेषताएँ बूलियन हैं, लेकिन पार्सल में पढ़ने / लिखने का कोई तरीका नहीं है।

आपको या तो मान को स्ट्रिंग के रूप में या बाइट के रूप में संग्रहीत करना होगा। यदि आप एक स्ट्रिंग के लिए जाते हैं, तो आपको बूलियन मान को पार्स करने के लिए Stringक्लास की स्थिर विधि का उपयोग करना होगा valueOf()। यह एक बाइट मुश्किल में इसे बचाने के रूप में प्रभावी नहीं है।

String.valueOf(theBoolean);

यदि आप एक बाइट के लिए जाते हैं तो आपको स्वयं एक रूपांतरण तर्क लागू करना होगा।

byte convBool = -1;
if (theBoolean) {
    convBool = 1;
} else {
    convBool = 0;
}

Parcelऑब्जेक्ट को अनमर्सहॉल करते समय आपको मूल प्रकार में रूपांतरण का ध्यान रखना होगा।


स्ट्रिंग का उपयोग करने का कोई कारण नहीं है। पार्स writeByte()विधि सीधे कॉल करने के बाद से बाइट का उपयोग करने का कोई कारण नहीं है writeInt()। रूपांतरण तर्क बहुत क्रियात्मक है। बस करो writeInt(boolean ? 1 : 0)औरboolean = readInt() != 0
यारोस्लाव Mytkalyk

1

यह प्रश्न पहले से ही अन्य लोगों द्वारा पूरी तरह से उत्तर दिया गया है, यदि आप इसे अपने दम पर करना चाहते हैं।

यदि आप अधिकांश निम्न-स्तर के पार्सलिंग कोड को संक्षिप्त करना या छिपाना पसंद करते हैं, तो आप उपयोग करने पर विचार कर सकते हैं पार्सल की हैंडलिंग को सरल बनाने के लिए कुछ समय पहले लिखे गए कुछ कोड का करने पर ।

पार्सल लिखना जितना आसान है:

parcelValues(dest, name, maxSpeed, weight, wheels, color, isDriving);

जहां रंग एक एनुम है और आइसिंग एक बुलियन है, उदाहरण के लिए।

पार्सल से पढ़ना भी ज्यादा कठिन नहीं है:

color = (CarColor)unparcelValue(CarColor.class.getClassLoader());
isDriving = (Boolean)unparcelValue();

बस "ParceldroidExample" पर एक नज़र डालें जो मैंने प्रोजेक्ट में जोड़ा था।

अंत में, यह क्रिएटर इनिशियलाइज़र को भी छोटा रखता है:

public static final Parcelable.Creator<Car> CREATOR =
    Parceldroid.getCreatorForClass(Car.class);

के लिए धन्यवाद .class.getClassLoader()
कूलमाइंड

0

Android (AOSP) स्रोतों में कई उदाहरण हैं। उदाहरण के लिए, PackageInfoवर्ग में एक बूलियन सदस्य होता है requiredForAllUsersऔर इसे निम्नानुसार क्रमबद्ध किया जाता है:

public void writeToParcel(Parcel dest, int parcelableFlags) {
    ...
    dest.writeInt(requiredForAllUsers ? 1 : 0);
    ...
}

private PackageInfo(Parcel source) {
    ...
    requiredForAllUsers = source.readInt() != 0;
    ...
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.