एंड्रॉइड पर एक गतिविधि से दूसरी में किसी ऑब्जेक्ट को कैसे पास करें


778

मैं अपने ग्राहक वर्ग के ऑब्जेक्ट को एक से भेजने Activityऔर दूसरे में प्रदर्शित करने पर काम करने की कोशिश कर रहा हूं Activity

ग्राहक वर्ग के लिए कोड:

public class Customer {

    private String firstName, lastName, Address;
    int Age;

    public Customer(String fname, String lname, int age, String address) {

        firstName = fname;
        lastName = lname;
        Age = age;
        Address = address;
    }

    public String printValues() {

        String data = null;

        data = "First Name :" + firstName + " Last Name :" + lastName
        + " Age : " + Age + " Address : " + Address;

        return data;
    }
}

मैं एक Activityसे दूसरे पर अपनी वस्तु भेजना चाहता हूं और फिर दूसरे पर डेटा प्रदर्शित करता हूं Activity

मैं उसे कैसे प्राप्त कर सकता हूं?


1
संभवतः आपको जनमत को देखते हुए स्वीकृत उत्तर को बदलना चाहिए।
रोहित विपिन मैथ्यूज

मैं Pacelable या Serializable के लिए ऑब्जेक्ट सेट करता था, लेकिन जब भी मैं अन्य चर जोड़ता हूं, मुझे Pacelable या Serializable के लिए सेट करने और सेट करने के लिए सभी कार्यों में इसे जोड़ना होगा। इसलिए मैंने गतिविधियों और अंशों के बीच स्थानांतरण करने के लिए डाटाकैच बनाया। github.com/kimkevin/AndroidDataCache ऑब्जेक्ट ट्रांसफर करना बेहद आसान है।
किम्केविन

जवाबों:


886

एक विकल्प यह हो सकता है कि आपका कस्टम वर्ग Serializableइंटरफ़ेस को लागू कर सकता है और फिर आप विधि के अतिरिक्त putExtra(Serializable..)संस्करण का उपयोग करके इरादे में ऑब्जेक्ट को पास कर सकते हैं Intent#putExtra()

स्यूडोकोड :

//To pass:
intent.putExtra("MyClass", obj);

// To retrieve object in second Activity
getIntent().getSerializableExtra("MyClass");

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

class MainClass implements Serializable {

    public MainClass() {}

    public static class ChildClass implements Serializable {

        public ChildClass() {}
    }
}

126
@OD: मेरे बचाव में, मैंने कभी नहीं कहा कि यह सबसे अच्छा विकल्प था; ओपी ने सिर्फ विकल्प मांगे और मैंने एक सुझाव दिया। फिर भी धन्यवाद।
सामूह

83
क्यों सीरियल एक अच्छा विकल्प नहीं है? यह एक प्रसिद्ध इंटरफ़ेस है, एक अच्छा मौका है कि लोगों की कक्षाएं पहले से ही इसे लागू कर सकती हैं (उदाहरण के लिए, ArrayList, पहले से ही Serializable है)। आपको केवल एक कक्षा से दूसरी कक्षा में उत्तीर्ण करने के लिए अतिरिक्त कोड जोड़ने के लिए अपने डेटा ऑब्जेक्ट को क्यों बदलना चाहिए? यह एक खराब डिजाइन की तरह लगता है। मैं कल्पना कर सकता हूं कि कुछ स्तर पर कुछ प्रदर्शन प्रभाव हो सकता है, लेकिन मुझे लगता है कि 99% मामलों में, लोग कम मात्रा में डेटा पारित कर रहे हैं, और वे परवाह नहीं करेंगे। सरल और पोर्टेबल कभी-कभी बेहतर भी होता है।
रात

16
@ उत्तर: क्या यह उत्तर ( stackoverflow.com/questions/2139134/… ) तब गलत है? वह कहते हैं कि Parcelable आईएस विशेष रूप से उस उद्देश्य (और बहुत तेजी से Serializable) के लिए बनाया गया है । मैं एक उलझन हूँ।
सुलामा

41
Parcelableगति के लिए अच्छा हो सकता है, लेकिन इसे लागू करना जटिल है। क्या होगा यदि आपके पास 8 ऑब्जेक्ट हैं जो आपको गतिविधियों के बीच से गुजरने की आवश्यकता है, तो क्या आप हर एक को बनाने जा रहे हैं Parcelable? यह Serializableबजाय उपयोग करने के लिए और अधिक समझ में आता है । जब आप कार्यान्वित Parcelableकरते हैं तो आपको बहुत सारे कोड को वर्ग में जोड़ना पड़ता है, और फ़ील्ड को बहुत विशिष्ट तरीके से ऑर्डर करना होता है; Serializableतुम नहीं। अंततः, मुझे लगता है कि यह नीचे आता है कि आप कितनी वस्तुओं से गुजर रहे हैं और आप क्या करने की कोशिश कर रहे हैं।
ब्लैकहैटसमुई

15
Serializableएक मानक जावा इंटरफ़ेस है। आप बस एक वर्ग को चिन्हित करते हैं, इंटरफ़ेस को जोड़कर, और जावा स्वचालित रूप से कुछ स्थितियों में इसे क्रमबद्ध करेगा। Parcelableएक Android विशिष्ट इंटरफ़ेस है जहाँ आप क्रमांकन को स्वयं कार्यान्वित करते हैं। इसे और अधिक कुशल बनाने के लिए बनाया गया था जो कि सीरियल बनाने योग्य है, और डिफ़ॉल्ट जावा धारावाहिक योजना के साथ कुछ समस्याओं को प्राप्त करने के लिए
गौरव अरोड़ा

311

अपनी कक्षा को धारावाहिक के साथ लागू करें। मान लीजिए कि यह आपकी इकाई वर्ग है:

import java.io.Serializable;

@SuppressWarnings("serial") //With this annotation we are going to hide compiler warnings
public class Deneme implements Serializable {

    public Deneme(double id, String name) {
        this.id = id;
        this.name = name;
    }

    public double getId() {
        return id;
    }

    public void setId(double id) {
        this.id = id;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    private double id;
    private String name;
}

हम deneएक्स एक्टिविटी से वाई ऑब्जेक्ट नामक ऑब्जेक्ट भेज रहे हैं । एक्स गतिविधि में कहीं;

Deneme dene = new Deneme(4,"Mustafa");
Intent i = new Intent(this, Y.class);
i.putExtra("sampleObject", dene);
startActivity(i);

Y गतिविधि में हमें वस्तु मिल रही है।

Intent i = getIntent();
Deneme dene = (Deneme)i.getSerializableExtra("sampleObject");

बस।


1
यह वास्तव में मेरे लिए मददगार था। धन्यवाद ... लेकिन पारित वस्तु प्राप्त करते समय, वाक्यविन्यास [Deneme dene = (Deneme) i.getSerializableExtra ("sampleObject") होना चाहिए; ] ... क्या यह ???
JibW

1
@ मुस्तफा गुवेन लेकिन मुझे classCastException: java.lang.Longऐसा करने से मिल रहा है। क्या आप कृपया बता सकते हैं कि क्यों?
शजील अफजल

मेरा उत्तर से कोई संबंध नहीं है। यह बहुत अलग बात है जो आपको मिल रही है। क्या आप अपने कोड साझा कर सकते हैं?
मुस्तफा गुवेन

1
बड़े POJO के लिए सीरियल बहुत धीमा है। बस का उपयोग करना बेहतर पैटर्न है।
स्टीवन मार्क फोर्ड

1
मुझे (Serializable)वस्तु का उपसर्ग क्यों करना चाहिए ?
अल्स्टन

123
  • वैश्विक स्थिर चर का उपयोग करना अच्छा सॉफ्टवेयर इंजीनियरिंग अभ्यास नहीं है।
  • किसी वस्तु के क्षेत्रों को आदिम डेटा प्रकारों में परिवर्तित करना एक व्यस्त कार्य हो सकता है
  • सीरियल करने योग्य का उपयोग करना ठीक है, लेकिन यह एंड्रॉइड प्लेटफॉर्म पर प्रदर्शन-कुशल नहीं है।
  • Parcelable विशेष रूप से Android के लिए डिज़ाइन किया गया है और आपको इसका उपयोग करना चाहिए। यहां एक सरल उदाहरण दिया गया है: एंड्रॉइड गतिविधियों के बीच कस्टम वस्तुओं को पास करना

आप इस साइट का उपयोग करके अपने लिए Parcelable कोड उत्पन्न कर सकते हैं ।


4
क्या होगा यदि मेरी वस्तु में Nested Arraylist हो?
डॉ। एनड्रो

10
अच्छी तरह से शायद, लेकिन एक को वास्तव में नमक के एक दाने के साथ `` प्रदर्शन '' लेना चाहिए। अगर वह लागू करने की कीमत पर आता है Parcelableतो मैं अपने POJO वर्गों को एंड्रॉइड-अज्ञेय और उपयोग करना चाहूंगा Serializable
VH-NZZ

मैं इस बात से सहमत नहीं हूं कि आपको Parcelable का उपयोग करना चाहिए। एक साधारण बस पैटर्न रनटाइम में बहुत अधिक कुशल है और बहुत सारे देव समय की एक बिल्ली को बचाता है।
स्टीवन मार्क फोर्ड

15
इस बेंचमार्क के अनुसार bitbucket.org/afrishman/androidserializationtest Serializable Ccelable की तुलना में बहुत तेज है। कृपया पार्सल के बारे में इस 5 साल पुरानी बकवास साझा करना बंद करें।
afrish

7
वैश्विक स्थिर चर "अच्छा सॉफ्टवेयर इंजीनियरिंग अभ्यास नहीं" कैसे हैं? आप एक सिंगलटन कैश और / या डेटा ग्रिड की तरह कुछ बना सकते हैं, फिर आईडी या समान के आसपास से गुजर सकते हैं। जब आप जावा में संदर्भों के चारों ओर से गुजरते हैं, तो आप वैश्विक स्थिर चर का उपयोग इस अर्थ में करते हैं, क्योंकि वे उसी वस्तु की ओर इशारा करते हैं।
breakline

111

अपनी वस्तु को JSON में बदलने के लिए और इरादे से इसे पास करने के लिए gson का उपयोग करें । नई गतिविधि में JSON को ऑब्जेक्ट में कनवर्ट करें।

अपने में build.gradle, इसे अपनी निर्भरता में जोड़ें

implementation 'com.google.code.gson:gson:2.8.4'

अपनी गतिविधि में, ऑब्जेक्ट को json-string में रूपांतरित करें:

Gson gson = new Gson();
String myJson = gson.toJson(vp);
intent.putExtra("myjson", myjson);

अपनी प्राप्त गतिविधि में, json-string को वापस मूल ऑब्जेक्ट में बदलें:

Gson gson = new Gson();
YourObject ob = gson.fromJson(getIntent().getStringExtra("myjson"), YourObject.class);

के लिए Kotlin यह काफी ही है

डेटा पास करें

val gson = Gson()
val intent = Intent(this, YourActivity::class.java)
intent.putExtra("identifier", gson.toJson(your_object))
startActivity(intent)

डेटा प्राप्त करें

val gson = Gson()
val yourObject = gson.fromJson<YourObject>(intent.getStringExtra("identifier"), YourObject::class.java)

3
इसका ओवरकिल, गन्स सिर्फ एक प्रकार का स्ट्रिंग क्रमिककरण है जोसन के लिए है, यह बेहतर है कि इसे सीरियलिबल या पैरासेबल लागू किया जा सके।
जेम्स रोइटर

14
यदि आपको किसी लाइब्रेरी (gson) का उपयोग करना हो तो हर वस्तु और हर परियोजना में (समय की बर्बादी) क्रमिक रूप से लागू करने की आवश्यकता नहीं है। और overkill के बारे में, वहाँ बाहर दोहरी और quadcore फोन theres, वे भी इस जवाब विचार के बाद एक सूची को संभाल कर सकते हैं।
sagits

4
मैं भी gson का उपयोग करने की सलाह दूंगा क्योंकि gson उपरोक्त के अलावा arraylists को भी क्रमबद्ध कर सकता है।
nurgasemetey

4
यह भी खूब रही! मेरे मामले में, मैं एक पुस्तकालय का उपयोग कर रहा हूं कि वस्तुएं क्रमबद्ध या पार्सल योग्य नहीं हैं। तो यह मेरा एकमात्र विकल्प afaik है
चाड बिंगहैम

2
यह "सर्वश्रेष्ठ" विकल्प है। कुछ कक्षाएं इतनी सरल हैं, आपको क्रमिक रूप से लागू करके उनके कार्यान्वयन को जटिल बनाने की आवश्यकता नहीं है
ओजोनुगवा जूड ओचलिफु

98

एक गतिविधि को कॉल करते समय

Intent intent = new Intent(fromClass.this,toClass.class).putExtra("myCustomerObj",customerObj);

InClass.java द्वारा गतिविधि प्राप्त करते हैं

Customer customerObjInToClass = getIntent().getExtras().getParcelable("myCustomerObj");

कृपया सुनिश्चित करें कि ग्राहक वर्ग पार्सल लागू करता है

public class Customer implements Parcelable {

    private String firstName, lastName, address;
    int age;

    /* all your getter and setter methods */

    public Customer(Parcel in ) {
        readFromParcel( in );
    }

    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
        public LeadData createFromParcel(Parcel in ) {
            return new Customer( in );
        }

        public Customer[] newArray(int size) {
            return new Customer[size];
        }
    };


    @Override
    public void writeToParcel(Parcel dest, int flags) {

        dest.writeString(firstName);
        dest.writeString(lastName);
        dest.writeString(address);
        dest.writeInt(age);
    }

    private void readFromParcel(Parcel in ) {

        firstName = in .readString();
        lastName  = in .readString();
        address   = in .readString();
        age       = in .readInt();
    }

अधवन, मुझे एक प्रश्न मिला। जब आप पहली इंटेंट क्लास बनाते हैं, तो आप पहले तर्क के रूप में fromClass.this से गुजरते हैं। क्या इस गतिविधि को प्राप्त करने वाले वर्ग में पुनः प्राप्त करने का कोई तरीका है?
न्यूमैन

1
मिल्लू, फ्रक्लेस से fr = (fromClass) getParent (); क्या यह आपको चाहिए?
विज्ञापन

Adhava, मैं वास्तव में यह किया है, लेकिन fr अशक्त है। कोई विचार क्यों?
न्यूमैन

miliu, कृपया अपना अपवाद ट्रेस साझा करें ताकि हम उस पर गौर कर सकें।
विज्ञापन

Parcelable में बहुत सारे आवश्यक बॉयलर प्लेट कोड की एक बिल्ली है और यह बहुत स्पष्ट रूप से समय की बर्बादी है। बल्कि एक बस का उपयोग करें। मेरी पोस्ट नीचे देखें।
स्टीवन मार्क फोर्ड

89

मेरे अनुभव में तीन मुख्य उपाय हैं, जिनमें से प्रत्येक अपने नुकसान और फायदे हैं:

  1. पार्सल को लागू करना

  2. धारावाहिक लागू करना

  3. किसी प्रकार की हल्की-फुल्की घटना बस लाइब्रेरी का उपयोग करना (उदाहरण के लिए, ग्रीनब्रोट्स इवेंटबस या स्क्वायर ओटो)

पार्सेबल - तेज और एंड्रॉइड मानक, लेकिन इसमें बहुत सारे बॉयलरप्लेट कोड हैं और इरादे को बाहर निकालते समय (गैर-दृढ़ता से टाइप किए गए) मानों को संदर्भ के लिए हार्ड-कोडेड स्ट्रिंग्स की आवश्यकता होती है।

सीरियल करने योग्य - शून्य बॉयलरप्लेट के करीब, लेकिन यह सबसे धीमा दृष्टिकोण है और इरादे को बाहर खींचते समय कठोर-कोडित तारों की भी आवश्यकता होती है (गैर-दृढ़ता से टाइप किया गया)।

इवेंट बस - शून्य बॉयलरप्लेट, सबसे तेज़ तरीका, और इसके लिए हार्ड-कोडिंग स्ट्रिंग्स की आवश्यकता नहीं है, लेकिन इसके लिए एक अतिरिक्त निर्भरता की आवश्यकता होती है (हालांकि आमतौर पर हल्के, ~ 40 KB)

मैंने दक्षता बेंचमार्क सहित इन तीन दृष्टिकोणों के आसपास एक बहुत विस्तृत तुलना पोस्ट की है।


4
लेख का लिंक मृत है। अभी भी वेबर्चिव पर उपलब्ध है: web.archive.org/web/20160917213123/http://…
OlivierH

यह शर्म की बात है कि लिंक नीचे है :(
Mauker

इवेंट बस के उपयोग की समस्या तब है जब लक्ष्य गतिविधि को उदाहरण के लिए रोटेशन के कारण फिर से बनाया गया है। इस मामले में लक्ष्य गतिविधि पास की गई वस्तु तक नहीं पहुँच पाती है क्योंकि यह वस्तु पहले कॉल के द्वारा बस से भस्म हो गई थी।
जूलियस 16

1
Parcelable सबसे तेज़ है और इस जनरेटर ( parcelabler.com ) के साथ, आप अपनी कक्षा पेस्ट कर सकते हैं और यह आपके लिए कोड उत्पन्न कर सकता है। सरल।
ByWeded

1
@ByWaleed ... मैं बिल्कुल सहमत हूं, मैं हमेशा इस साइट का उपयोग करता हूं, बिना किसी परेशानी के सामान बनाता है। हालाँकि, मेरे पास बहुत से असफल प्रयास हुए हैं, जब मैं एक POJO का उपयोग करने का प्रयास करता हूं जो किसी अन्य ऑब्जेक्ट से बना होता है। किसी कारण से इसका पुट वास्तव में काम नहीं करता है।
यो एप्स

42

मुझे एक सरल और सुरुचिपूर्ण विधि मिली:

  • न पार्सलबल
  • कोई सीरियल नहीं
  • कोई स्थैतिक क्षेत्र
  • कोई इवेंट बस नहीं

विधि 1

पहली गतिविधि के लिए कोड:

    final Object objSent = new Object();
    final Bundle bundle = new Bundle();
    bundle.putBinder("object_value", new ObjectWrapperForBinder(objSent));
    startActivity(new Intent(this, SecondActivity.class).putExtras(bundle));        
    Log.d(TAG, "original object=" + objSent);

दूसरी गतिविधि के लिए कोड:

    final Object objReceived = ((ObjectWrapperForBinder)getIntent().getExtras().getBinder("object_value")).getData();
    Log.d(TAG, "received object=" + objReceived);

आपको वही मिलेगा objSentऔर होगा , इसलिए वे समान हैं।objReceivedhashCode

लेकिन हम इस तरह से एक जावा ऑब्जेक्ट क्यों पारित कर सकते हैं?

दरअसल, android binder java object के लिए Global JNI Reference बनाएगी और इस JNI ऑब्जेक्ट के लिए कोई संदर्भ नहीं होने पर यह Global JNI संदर्भ जारी करेगी। बाइंडर इस वैश्विक JNI संदर्भ को Binder ऑब्जेक्ट में बचाएगा।

* चेतावनी: यह विधि केवल तब तक काम करती है जब तक कि दो गतिविधियाँ एक ही प्रक्रिया में न चलें, अन्यथा ClassCastException को (ObjectWrapperForBinder) getIntent ()। GetExtras ()। GetBinder ("object_value") * पर फेंक दें।

कक्षा ObjectWrapperForBinder डिफिनेशन

public class ObjectWrapperForBinder extends Binder {

    private final Object mData;

    public ObjectWrapperForBinder(Object data) {
        mData = data;
    }

    public Object getData() {
        return mData;
    }
}

विधि 2

  • प्रेषक के लिए,
    1. JNI वैश्विक संदर्भ तालिका (JNIEnv :: NewGlobalRef) के माध्यम से अपने जावा ऑब्जेक्ट को जोड़ने के लिए कस्टम देशी विधि का उपयोग करें
    2. रिटर्न पूर्णांक (वास्तव में, JNIEnv :: NewGlobalRef रिटर्न जॉबजेक्ट, जो एक पॉइंटर है, हम इसे आपके इंटेंट तक सुरक्षित रूप से डाल सकते हैं) (इंटेंट :: putExtra के माध्यम से)
  • रिसीवर के लिए
    1. आशय से पूर्णांक प्राप्त करें (आशय :: getInt के माध्यम से)
    2. JNI वैश्विक संदर्भ तालिका (JNIEnv :: NewLocalRef के माध्यम से) से अपने जावा ऑब्जेक्ट को पुनर्स्थापित करने के लिए कस्टम मूल विधि का उपयोग करें
    3. JNI वैश्विक संदर्भ तालिका से आइटम निकालें (JNIEnv :: DeleteGlobalRef के माध्यम से),

लेकिन विधि 2 में थोड़ा लेकिन गंभीर मुद्दा है, यदि रिसीवर जावा ऑब्जेक्ट को पुनर्स्थापित करने में विफल रहता है (उदाहरण के लिए, जावा ऑब्जेक्ट को पुनर्स्थापित करने से पहले कुछ अपवाद होता है, या रिसीवर गतिविधि बिल्कुल भी मौजूद नहीं है), तो जावा ऑब्जेक्ट एक बन जाएगा अनाथ या स्मृति रिसाव, विधि 1 में यह समस्या नहीं है, क्योंकि एंड्रॉइड बाइंडर इस अपवाद को संभाल लेगा

विधि 3

जावा ऑब्जेक्ट को दूरस्थ रूप से आह्वान करने के लिए, हम जावा ऑब्जेक्ट का वर्णन करने के लिए एक डेटा अनुबंध / इंटरफ़ेस बनाएंगे, हम सहायता फ़ाइल का उपयोग करेंगे

IDataContract.aidl

package com.example.objectwrapper;
interface IDataContract {
    int func1(String arg1);
    int func2(String arg1);
}

पहली गतिविधि के लिए कोड

    final IDataContract objSent = new IDataContract.Stub() {

        @Override
        public int func2(String arg1) throws RemoteException {
            // TODO Auto-generated method stub
            Log.d(TAG, "func2:: arg1=" + arg1);
            return 102;
        }

        @Override
        public int func1(String arg1) throws RemoteException {
            // TODO Auto-generated method stub
            Log.d(TAG, "func1:: arg1=" + arg1);
            return 101;
        }
    };
    final Bundle bundle = new Bundle();
    bundle.putBinder("object_value", objSent.asBinder());
    startActivity(new Intent(this, SecondActivity.class).putExtras(bundle));
    Log.d(TAG, "original object=" + objSent);

दूसरी गतिविधि के लिए कोड:

Android बदलें: प्रक्रिया की विशेषता AndroidManifest.xml में एक अन्य प्रक्रिया में चलने वाली दूसरी गतिविधि को सुनिश्चित करने के लिए एक गैर-रिक्त प्रक्रिया नाम के लिए।

    final IDataContract objReceived = IDataContract.Stub.asInterface(getIntent().getExtras().getBinder("object_value"));
    try {
        Log.d(TAG, "received object=" + objReceived + ", func1()=" + objReceived.func1("test1") + ", func2()=" + objReceived.func2("test2"));
    } catch (RemoteException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

इस प्रकार, हम दो गतिविधियों के बीच एक इंटरफ़ेस पास कर सकते हैं भले ही वे अलग-अलग प्रक्रिया में चलें, और इंटरफ़ेस विधि को दूरस्थ रूप से कॉल करें

विधि 4

पद्धति 3 पर्याप्त सरल नहीं लगती है क्योंकि हमें एक सहायक इंटरफ़ेस लागू करना चाहिए। यदि आप केवल सरल कार्य करना चाहते हैं और विधि वापसी मान अनावश्यक है, तो हम android.os.Messenger का उपयोग कर सकते हैं

पहली गतिविधि के लिए कोड (प्रेषक):

public class MainActivity extends Activity {
    private static final String TAG = "MainActivity";

    public static final int MSG_OP1 = 1;
    public static final int MSG_OP2 = 2;

    public static final String EXTRA_MESSENGER = "messenger";

    private final Handler mHandler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            // TODO Auto-generated method stub
            Log.e(TAG, "handleMessage:: msg=" + msg);
            switch (msg.what) {
            case MSG_OP1:

                break;
            case MSG_OP2:
                break;

            default:

                break;
            }
            super.handleMessage(msg);
        }

    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        startActivity(new Intent(this, SecondActivity.class).putExtra(EXTRA_MESSENGER, new Messenger(mHandler)));
    }
}

दूसरी गतिविधि के लिए कोड (रिसीवर):

public class SecondActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);

        final Messenger messenger = getIntent().getParcelableExtra(MainActivity.EXTRA_MESSENGER);
        try {
            messenger.send(Message.obtain(null, MainActivity.MSG_OP1, 101, 1001, "10001"));
            messenger.send(Message.obtain(null, MainActivity.MSG_OP2, 102, 1002, "10002"));
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
}

सभी Messenger.send एक हैंडलर में अतुल्यकालिक और क्रमिक रूप से निष्पादित करेंगे।

वास्तव में, android.os.Messenger भी एक सहायक इंटरफ़ेस है, यदि आपके पास Android स्रोत कोड है, तो आप IMessenger.aidl नामक एक फ़ाइल पा सकते हैं

package android.os;

import android.os.Message;

/** @hide */
oneway interface IMessenger {
    void send(in Message msg);
}

क्षमा करें, मैंने यह नहीं देखा कि आपने अपने उत्तर में बाध्यकारी था और साथ ही मुझे लगता है कि आपका उत्तर भी बहुत सुंदर है।
स्किडनर 19

वाह .... इस आदमी की पहली विधि जबरदस्त है ..... जब आपके पास बहुत बड़ी / बड़ी आकार की वस्तुएं हैं जो अच्छी तरह से काम करती हैं
करण

मैं उपयोगकर्ता विधि one.So, आप मेरा समय बचाते हैं। धन्यवाद;
श्वेलियम

ObjectWrapperForBinder विधि के लिए बहुत बहुत धन्यवाद, वास्तव में मदद करता है!
व्लादिमीर टॉल्स्टिकोव

40

आप ऑब्जेक्ट के डेटा को अस्थायी स्ट्रिंग्स और इन्ट्स में भी लिख सकते हैं, और उन्हें गतिविधि में पास कर सकते हैं। बेशक इस तरह से, आपको डेटा ट्रांसपोर्ट किया जाता है, लेकिन ऑब्जेक्ट ही नहीं।

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

String fName_temp   = yourObject.getFname();
String lName_temp   = yourObject.getLname();
String age_temp     = yourObject.getAge();
String address_temp = yourObject.getAddress();

Intent i = new Intent(this, ToClass.class);
i.putExtra("fname", fName_temp);
i.putExtra("lname", lName_temp);
i.putExtra("age", age_temp);
i.putExtra("address", address_temp);

startActivity(i);

आप उन्हें सीधे अस्थायी आइवर के बजाय पास कर सकते हैं, लेकिन इस तरह यह स्पष्ट है, मेरी राय में। इसके अतिरिक्त, आप अस्थायी आइवर को अशक्त करने के लिए सेट कर सकते हैं ताकि वे गारबेलकोलर द्वारा जल्दी साफ हो जाएं।

सौभाग्य!

एक साइड नोट पर: अपनी स्वयं की प्रिंट विधि लिखने के बजाय ओवरराइड () को ओवरराइड करें।

जैसा कि नीचे टिप्पणी में बताया गया है, यह है कि आप अपना डेटा वापस किसी अन्य गतिविधि में कैसे प्राप्त करते हैं:

String fName = getIntent().getExtras().getInt("fname");

9
अपना डेटा फिर से प्राप्त करें: स्ट्रिंग fName = getIntent ()। getExtras ()। getInt ("fname");
एलिस्टर

2
डेटा वापस पाने के लिए: Bundle extras = getIntent().getExtras(); String val = extras.getString("fname");
एरिक लेसचिंस्की

1
यह बड़े POJO के लिए जल्दी से प्रभावी हो सकता है। बल्कि एक बस का उपयोग करें। मेरी पोस्ट नीचे देखें।
स्टीवन मार्क फोर्ड

जैसा कि मैंने अपने उत्तर में उल्लेख किया है, यह साधारण यूसेज के लिए है, जहाँ आपको स्वयं वस्तु की आवश्यकता नहीं है, बल्कि इसके कुछ मूल्यों की आवश्यकता है। यह जटिल usecases के लिए एक स्थिति होने के लिए मानसिक रूप से नहीं है।
MJB

1
एक वस्तु को पास करने के लिए अच्छा विचार है, लेकिन मैं अपनी वस्तु के अज्ञात आकार की एक सरणी को पास करने की कोशिश कर रहा हूं। शायद आपका समाधान ऑब्जेक्ट सरणियों को पारित करने के लिए नहीं है।
मुहम्मद साकिब

25

मैंने एक सिंगलटन हेल्पर क्लास बनाई जो अस्थायी वस्तुओं को रखती है।

public class IntentHelper {

    private static IntentHelper _instance;
    private Hashtable<String, Object> _hash;

    private IntentHelper() {
        _hash = new Hashtable<String, Object>();
    }

    private static IntentHelper getInstance() {
        if(_instance==null) {
            _instance = new IntentHelper();
        }
        return _instance;
    }

    public static void addObjectForKey(Object object, String key) {
        getInstance()._hash.put(key, object);
    }

    public static Object getObjectForKey(String key) {
        IntentHelper helper = getInstance();
        Object data = helper._hash.get(key);
        helper._hash.remove(key);
        helper = null;
        return data;
    }
}

अपने ऑब्जेक्ट्स को Intent के भीतर रखने के बजाय, IntentHelper का उपयोग करें:

IntentHelper.addObjectForKey(obj, "key");

अपनी नई गतिविधि के अंदर, आप वस्तु प्राप्त कर सकते हैं:

Object obj = (Object) IntentHelper.getObjectForKey("key");

ध्यान रखें कि एक बार लोड होने पर, अनावश्यक संदर्भों से बचने के लिए ऑब्जेक्ट को हटा दिया जाता है।


1
अच्छा विचार! इसके अतिरिक्त आप एक अतिरिक्त श्रेणी ObjectContainer {ऑब्जेक्ट, obj बना सकते हैं; बूलियन स्थायी; ....} आइडिया यह है कि, यदि आप ऑब्जेक्ट को स्थिर रखना चाहते हैं और जब आप कॉल प्राप्त करते हैं, तो उसे हटाने की आवश्यकता नहीं है, तो आप ऐड विधि में एक बूलियन पास कर सकते हैं। यह कुछ वैश्विक वस्तुओं को रखने में मदद करेगा। जैसे एक खुला ब्लूटूथ कनेक्शन हो सकता है
उमर

1
प्यारा है, लेकिन पहिया का फिर से आविष्कार नहीं करते हैं। बस पैटर्न सुरुचिपूर्ण और अधिक शक्तिशाली है। मेरी पोस्ट नीचे देखें।
स्टीवन मार्क फोर्ड

@StevenMarkFord तो क्या बस पैटर्न अभी भी इस दिन सच है? : मैं गतिविधियों के बीच इस एक्सेस डेटा की तरह एक कोड के साथ एक codebase सुधार करने के लिए कोशिश कर रहा हूँ BookActivity.getInstance().recommendationResponseमेंRoomsActivity
Woppi

जब प्राप्त गतिविधि से निर्मित किया गया है (उदाहरण के लिए स्क्रीन रोटेशन पर) objहो जाता है null। इससे बचने के लिए, objइसे फिर से प्राप्त करने के लिए कहीं संग्रहीत किया जाना चाहिए। वास्तव में Json समाधान वस्तु डेटा को आशय में संग्रहीत करता है।
साल्वाडोर

25

कुछ तरीके हैं जिनके द्वारा आप अन्य कक्षाओं या गतिविधि में चर या वस्तुओं तक पहुंच सकते हैं।

ए। डेटाबेस

B. साझा प्राथमिकताएँ।

सी। वस्तु क्रमांकन।

डी। एक वर्ग जो सामान्य डेटा को धारण कर सकता है, उसे कॉमन यूटिलिटीज़ के रूप में नामित किया जा सकता है। यह आप पर निर्भर करता है।

इंटेंस और पार्सलेबल इंटरफेस के माध्यम से ई पासिंग डेटा।

यह आपकी परियोजना की जरूरतों पर निर्भर करता है।

डेटाबेस

SQLite एक खुला स्रोत डेटाबेस है जो Android में एम्बेडेड है। SQLite, SQL सिंटैक्स, लेन-देन और तैयार कथनों जैसे मानक रिलेशनल डेटाबेस सुविधाओं का समर्थन करता है।

ट्यूटोरियल

B. साझा प्राथमिकताएँ

मान लीजिए कि आप उपयोगकर्ता नाम संग्रहीत करना चाहते हैं। तो अब दो चीजें होंगी, एक मुख्य उपयोगकर्ता नाम, मूल्य मान।

कैसे स्टोर करें

 // Create object of SharedPreferences.
 SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);

 //Now get Editor
 SharedPreferences.Editor editor = sharedPref.edit();

 //Put your value
 editor.putString("userName", "stackoverlow");

 //Commits your edits
 editor.commit();

PutString (), putBoolean (), putInt (), putFloat (), और putLong () का उपयोग करके आप अपने इच्छित dtatype को बचा सकते हैं।

कैसे लायें

SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
String userName = sharedPref.getString("userName", "Not Available");

http://developer.android.com/reference/android/content/SharedPreferences.html

C. वस्तु क्रमबद्धता

ऑब्जेक्ट सेर्लाइज़ेशन का उपयोग किया जाता है यदि हम किसी नेटवर्क पर भेजने के लिए ऑब्जेक्ट स्थिति को सहेजना चाहते हैं या आप इसे अपने उद्देश्य के लिए भी उपयोग कर सकते हैं।

जावा बीन्स का उपयोग करें और अपने खेतों में से एक के रूप में स्टोर करें और उसके लिए गेटर्स और सेटर का उपयोग करें।

JavaBeans जावा क्लासेस हैं जिनके गुण हैं। गुणों को निजी उदाहरण चर के रूप में सोचें। चूंकि वे निजी हैं, इसलिए उनकी कक्षा के बाहर पहुंचने का एकमात्र तरीका कक्षा में विधियों के माध्यम से है। किसी संपत्ति के मूल्य को बदलने वाले तरीकों को सेटर विधियां कहा जाता है, और संपत्ति के मूल्य को पुनः प्राप्त करने वाले तरीकों को गेटर विधियां कहा जाता है।

public class VariableStorage implements Serializable  {

    private String inString;

    public String getInString() {
        return inString;
    }

    public void setInString(String inString) {
        this.inString = inString;
    }
}

चर का उपयोग करके अपने मेल विधि में सेट करें

VariableStorage variableStorage = new VariableStorage();
variableStorage.setInString(inString);

फिर इस ऑब्जेक्ट को क्रमांकित करने के लिए ऑब्जेक्ट क्रमांकन का उपयोग करें और अपने अन्य वर्ग में इस ऑब्जेक्ट को डिसेरिएलाइज़ करें।

क्रमांकन में किसी ऑब्जेक्ट को बाइट्स के अनुक्रम के रूप में दर्शाया जा सकता है जिसमें ऑब्जेक्ट के डेटा के साथ-साथ ऑब्जेक्ट के प्रकार और ऑब्जेक्ट में संग्रहीत डेटा के प्रकार के बारे में जानकारी शामिल होती है।

किसी सीरियल किए गए ऑब्जेक्ट को किसी फ़ाइल में लिखे जाने के बाद, इसे फ़ाइल से पढ़ा जा सकता है और डीसर्विलाइज़ किया जा सकता है। अर्थात्, सूचना और बाइट्स जो ऑब्जेक्ट का प्रतिनिधित्व करते हैं और इसके डेटा का उपयोग मेमोरी में ऑब्जेक्ट को फिर से बनाने के लिए किया जा सकता है।

यदि आप इसके लिए ट्यूटोरियल चाहते हैं:

डी। आम उपयोगिताएँ

आप अपने आप से एक वर्ग बना सकते हैं जिसमें आम डेटा हो सकता है जिसकी आपको अपने प्रोजेक्ट में अक्सर आवश्यकता होती है।

नमूना

public class CommonUtilities {

    public static String className = "CommonUtilities";

}

इंटों के माध्यम सेपासिंग डेटा

कृपया पासिंग डेटा के इस विकल्प के लिए पार्सलेबल कक्षाओं का उपयोग करके गतिविधियों के बीच पास करने के लिए ट्यूटोरियल एंड्रॉइड - पार्सल डेटा देखें ।


22

Customerनिम्नलिखित के रूप में अपनी खुद की कक्षा बनाएँ :

import import java.io.Serializable;
public class Customer implements Serializable
{
    private String name;
    private String city;

    public Customer()
    {

    }
    public Customer(String name, String city)
    {
        this.name= name;
        this.city=city;
    }
    public String getName() 
    {
        return name;
    }
    public void setName(String name) 
    {
        this.name = name;
    }
    public String getCity() 
    {
        return city;
    }
    public void setCity(String city) 
    {
        this.city= city;
    }

}

अपनी onCreate()विधि में

@Override
protected void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_top);

    Customer cust=new Customer();
    cust.setName("abc");
    cust.setCity("xyz");

    Intent intent=new Intent(abc.this,xyz.class);
    intent.putExtra("bundle",cust);
    startActivity(intent); 
}

में xyz activityवर्ग आप निम्नलिखित कोड का उपयोग करने की जरूरत है:

Intent intent=getIntent();
Customer cust=(Customer)intent.getSerializableExtra("bundle");
textViewName.setText(cust.getName());
textViewCity.setText(cust.getCity());

अपने कोड ..Check आप पुट के लिए कुंजी के रूप में "समूह" को गुजर रहे हैं ग्राहक obj और "वर्ग" ..pls या तो "वर्ग" या "समूह" को .. एक कुंजी का उपयोग से हो रही
एके जोशी

मुझे त्रुटि का सामना करना पड़ता है: पार्सलबल का सामना करना पड़ा IOException लेखन क्रमिक वस्तु
अरुल मणि

15

सबसे अच्छा तरीका है कि आपके आवेदन में एक वर्ग (इसे नियंत्रण कहो) है जो 'ग्राहक' (आपके मामले में) प्रकार का एक स्थिर चर रखेगा। अपनी गतिविधि A में वैरिएबल को प्रारंभ करें।

उदाहरण के लिए:

Control.Customer = CustomerClass;

फिर गतिविधि बी पर जाएं और इसे नियंत्रण वर्ग से प्राप्त करें। चर का उपयोग करने के बाद एक अशक्त असाइन करना न भूलें, अन्यथा स्मृति बर्बाद हो जाएगी।


4
@aez क्योंकि यह एक डिज़ाइन के दृष्टिकोण से टेढ़ा है और बुरी तरह से टूट जाएगा यदि आशय किसी अन्य प्रक्रिया में है।

7
जब आप एक्टिविटी बी को एंड्रॉइड द्वारा मार सकते हैं तो आपके ऐप को फिर से शुरू करने पर आप मुद्दों पर चलेंगे क्योंकि ऑब्जेक्ट सेव नहीं होगा।
रयान आर

15
public class MyClass implements Serializable{
    Here is your instance variable
}

अब आप startActivity में इस वर्ग की वस्तु को पास करना चाहते हैं। बस इस का उपयोग करें:

Bundle b = new Bundle();
b.putSerializable("name", myClassObject);
intent.putExtras(b);

यह यहाँ काम करता है क्योंकि MyClass लागू करता है Serializable


क्या आप कृपया समझा सकते हैं या अधिक विस्तार से बता सकते हैं
Amitsharma

होमवर्कडॉट होमवर्कडैटा = होमवर्क्सलिस्ट.गेट (स्थिति); आशय अभिप्राय = नया आशय (ग, होमवर्क एक्टिविटीडेटेल.क्लास); बंडल b = नया बंडल (); b.putSerializable ("कम्प्लीटडाटा", होमवर्कडाटा); intent.putExtras (ख); c.startActivity (आशय); ऑब्जेक्ट ऐड के समय मुझे ऑब्जेक्ट एलीमेंट्स जोड़ने के लिए कुछ त्रुटि मिलती है, क्या हम इसके साथ पूरी ऑब्जेक्ट पास नहीं कर सकते हैं
अमिटशर्मा


12

यदि आप सामू के वर्णन के तरीके का उपयोग करते हैं, तो याद रखें कि केवल आदिम मान भेजे जा सकते हैं। यही है, मूल्य जो पार्स करने योग्य हैं। इसलिए, यदि आपकी वस्तु में जटिल वस्तुएं हैं, तो ये अनुसरण नहीं करेंगे। उदाहरण के लिए, बिटमैप, हैशपैप आदि जैसे चर ... ये इरादे से गुजरने के लिए मुश्किल हैं।

सामान्य तौर पर मैं स्ट्रिंग, पूर्णांक, बूलियन आदि जैसे, एक्स्ट्रा कलाकार के रूप में केवल आदिम डेटाटाइप्स भेजने के लिए अपने मामले यह होगा में आप सलाह होगा: String fname, String lname, int age, और String address

मेरी राय: अधिक जटिल वस्तुओं को एक ContentProvider , SDCard , आदि को लागू करने से बेहतर साझा किया जाता है । यह एक स्थिर चर का उपयोग करना भी संभव है , लेकिन यह तेजी से त्रुटि-प्रवण कोड हो सकता है ...

लेकिन फिर, यह सिर्फ मेरी व्यक्तिपरक राय है।


8

मैं डेटा को एक एक्टिविटी से दूसरी एक्टिविटी में भेजने के लिए पार्सल का इस्तेमाल कर रहा हूं। यहाँ मेरा कोड है जो मेरी परियोजना में ठीक काम करता है।

public class Channel implements Serializable, Parcelable {

    /**  */
    private static final long serialVersionUID = 4861597073026532544L;

    private String cid;
    private String uniqueID;
    private String name;
    private String logo;
    private String thumb;


    /**
     * @return The cid
     */
    public String getCid() {
        return cid;
    }

    /**
     * @param cid
     *     The cid to set
     */
    public void setCid(String cid) {
        this.cid = cid;
    }

    /**
     * @return The uniqueID
     */
    public String getUniqueID() {
        return uniqueID;
    }

    /**
     * @param uniqueID
     *     The uniqueID to set
     */
    public void setUniqueID(String uniqueID) {
        this.uniqueID = uniqueID;
    }

    /**
     * @return The name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name
     *            The name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return the logo
     */
    public String getLogo() {
        return logo;
    }

    /**
     * @param logo
     *     The logo to set
     */
    public void setLogo(String logo) {
        this.logo = logo;
    }

    /**
     * @return the thumb
     */
    public String getThumb() {
        return thumb;
    }

    /**
     * @param thumb
     *     The thumb to set
     */
    public void setThumb(String thumb) {
        this.thumb = thumb;
    }


    public Channel(Parcel in) {
        super();
        readFromParcel(in);
    }

    public static final Parcelable.Creator<Channel> CREATOR = new Parcelable.Creator<Channel>() {
        public Channel createFromParcel(Parcel in) {
            return new Channel(in);
        }

        public Channel[] newArray(int size) {

            return new Channel[size];
        }
    };

    public void readFromParcel(Parcel in) {
        String[] result = new String[5];
        in.readStringArray(result);

        this.cid = result[0];
        this.uniqueID = result[1];
        this.name = result[2];
        this.logo = result[3];
        this.thumb = result[4];
    }

    public int describeContents() {
        return 0;
    }

    public void writeToParcel(Parcel dest, int flags) {

        dest.writeStringArray(new String[] { this.cid, this.uniqueID,
                this.name, this.logo, this.thumb});
    }
}

गतिविधि में इसका उपयोग इस तरह करें:

Bundle bundle = new Bundle();
bundle.putParcelableArrayList("channel",(ArrayList<Channel>) channels);
Intent intent = new Intent(ActivityA.this,ActivityB.class);
intent.putExtras(bundle);
startActivity(intent);

गतिविधिबी में डेटा प्राप्त करने के लिए इसे इस तरह उपयोग करें:

Bundle getBundle = this.getIntent().getExtras();
List<Channel> channelsList = getBundle.getParcelableArrayList("channel");

7

आप उस कक्षा का उपयोग करने का प्रयास कर सकते हैं। सीमा यह है कि इसे एक प्रक्रिया के बाहर उपयोग नहीं किया जा सकता है।

एक गतिविधि:

 final Object obj1 = new Object();
 final Intent in = new Intent();
 in.putExtra(EXTRA_TEST, new Sharable(obj1));

अन्य गतिविधि:

final Sharable s = in.getExtras().getParcelable(EXTRA_TEST);
final Object obj2 = s.obj();

public final class Sharable implements Parcelable {

    private Object mObject;

    public static final Parcelable.Creator < Sharable > CREATOR = new Parcelable.Creator < Sharable > () {
        public Sharable createFromParcel(Parcel in ) {
            return new Sharable( in );
        }


        @Override
        public Sharable[] newArray(int size) {
            return new Sharable[size];
        }
    };

    public Sharable(final Object obj) {
        mObject = obj;
    }

    public Sharable(Parcel in ) {
        readFromParcel( in );
    }

    Object obj() {
        return mObject;
    }


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


    @Override
    public void writeToParcel(final Parcel out, int flags) {
        final long val = SystemClock.elapsedRealtime();
        out.writeLong(val);
        put(val, mObject);
    }

    private void readFromParcel(final Parcel in ) {
        final long val = in .readLong();
        mObject = get(val);
    }

    /////

    private static final HashMap < Long, Object > sSharableMap = new HashMap < Long, Object > (3);

    synchronized private static void put(long key, final Object obj) {
        sSharableMap.put(key, obj);
    }

    synchronized private static Object get(long key) {
        return sSharableMap.remove(key);
    }
}

6

इस गतिविधि से एक और गतिविधि शुरू करें और बंडल ऑब्जेक्ट के माध्यम से पैरामीटर पास करें

Intent intent = new Intent(getBaseContext(), YourActivity.class);
intent.putExtra("USER_NAME", "xyz@gmail.com");
startActivity(intent);

डेटा को किसी अन्य गतिविधि पर ले जाएं (YourActivity)

String s = getIntent().getStringExtra("USER_NAME");

यह सरल प्रकार के डेटा प्रकार के लिए ठीक है। लेकिन अगर आप गतिविधि के बीच में जटिल डेटा पास करना चाहते हैं। यू पहले इसे क्रमबद्ध करने की आवश्यकता है।

यहां हमारे पास एम्प्लाई मॉडल है

class Employee{
    private String empId;
    private int age;
    print Double salary;

    getters...
    setters...
}

आप इस तरह के जटिल डेटा को क्रमबद्ध करने के लिए Google द्वारा प्रदान किए गए Gson lib का उपयोग कर सकते हैं

String strEmp = new Gson().toJson(emp);
Intent intent = new Intent(getBaseContext(), YourActivity.class);
intent.putExtra("EMP", strEmp);
startActivity(intent);

Bundle bundle = getIntent().getExtras();
String empStr = bundle.getString("EMP");
            Gson gson = new Gson();
            Type type = new TypeToken<Employee>() {
            }.getType();
            Employee selectedEmp = gson.fromJson(empStr, type);

TypeToken <> पदावनत है। वैकल्पिक क्या है?
राघवेंद्र एम

6

यह सवाल एक अन्य स्टैक ओवरफ्लो प्रश्न में भी चर्चा की गई है। कृपया Serializable का उपयोग करके इरादे के माध्यम से डेटा पास करने के लिए एक समाधान पर एक नज़र है । मुख्य बिंदु Bundleऑब्जेक्ट का उपयोग करने के बारे में है जो अंदर आवश्यक डेटा संग्रहीत करता है Intent

 Bundle bundle = new Bundle();

 bundle.putSerializable(key1, value1);
 bundle.putSerializable(key2, value2);
 bundle.putSerializable(key3, value3);

 intent.putExtras(bundle);

मान निकालने के लिए:

 Bundle bundle = new Bundle();

 for (String key : bundle.keySet()) {
 value = bundle.getSerializable(key));
 }

लाभ Serializableइसकी सादगी है। हालांकि, आपको Parcelableविधि का उपयोग करने पर विचार करना चाहिए यदि आपको कई डेटा स्थानांतरित करने की आवश्यकता है, क्योंकि Parcelableविशेष रूप से एंड्रॉइड के लिए डिज़ाइन किया गया है और यह की तुलना में अधिक कुशल है Serializable। आप Parcelableकक्षा का उपयोग करके बना सकते हैं :

  1. एक ऑनलाइन उपकरण - parcelabler
  2. एंड्रॉइड स्टूडियो के लिए एक प्लगइन - एंड्रॉइड पार्सलेबल जनरेटर

5

बीन क्लास की तरह एक वर्ग क्रेट करें और Serializableइंटरफ़ेस को लागू करें। फिर हम इसे intentविधि के माध्यम से पारित कर सकते हैं , उदाहरण के लिए:

intent.putExtra("class", BeanClass);

फिर इसे अन्य गतिविधि से प्राप्त करें, उदाहरण के लिए:

BeanClass cb = intent.getSerializableExtra("class");

5

अपने कस्टम वर्ग में इस तरह दो तरीके बनाएँ

public class Qabir {

    private int age;
    private String name;

    Qabir(){
    }

    Qabir(int age,String name){
        this.age=age; this.name=name;
    }   

    // method for sending object
    public String toJSON(){
        return "{age:" + age + ",name:\"" +name +"\"}";
    }

    // method for get back original object
    public void initilizeWithJSONString(String jsonString){

        JSONObject json;        
        try {
            json =new JSONObject(jsonString );
            age=json.getInt("age");
            name=json.getString("name");
        } catch (JSONException e) {
            e.printStackTrace();
        } 
    }
}

अब आपके प्रेषक गतिविधि में ऐसा करते हैं

Qabir q= new Qabir(22,"KQ");    
Intent in=new Intent(this,SubActivity.class);
in.putExtra("obj", q.toJSON());
startActivity( in);

और अपने रिसीवर गतिविधि में

Qabir q =new Qabir();
q.initilizeWithJSONString(getIntent().getStringExtra("obj"));

3

हाँ, एक स्थिर वस्तु का उपयोग करना कस्टम गैर-अनुक्रमिक वस्तुओं के साथ ऐसा करने का सबसे आसान तरीका है।


हाँ, मुझे लगता है कि मैं वास्तव में आपसे सहमत हूँ। उन वस्तुओं staticको बनाना बेहतर वर्कअराउंड है अगर putExtra()आप हर उस संपत्ति के लिए निवेश करना अव्यावहारिक है, जिस पर आप गुजरना चाहते हैं। उदाहरण के लिए, अभी, मैं एक ArrayListऑब्जेक्ट पास करना चाहता हूं । मैं staticइसके बजाय अपने ArrayList बना सकता हूँ ।
मैथ्यू क्विरोस

3

Android गतिविधि ऑब्जेक्ट्स को नष्ट और पुनर्गठित किया जा सकता है। तो, आपको उन्हें देखने के लिए एक और दृष्टिकोण का उपयोग करने की आवश्यकता होगी - या उनके द्वारा बनाई गई कोई भी वस्तु !!! - यूपी। यही है, आप स्थैतिक वर्ग के संदर्भ के रूप में पारित कर सकते हैं, लेकिन फिर ऑब्जेक्ट हैंडल (जावा इन "संदर्भों" को कॉल करता है, जैसा कि स्मॉलकॉइन करता है; लेकिन वे सी या असेंबली के अर्थ में संदर्भ नहीं हैं) संभवतः बाद में अमान्य हो जाएंगे क्योंकि एक "सुविधा" Android OE की किसी भी गतिविधि का सर्वनाश हो सकता है और उसे बाद में पुनर्गठित किया जा सकता है।

मूल प्रश्न "एंड्रॉइड में एक गतिविधि से दूसरे में ऑब्जेक्ट कैसे पास करें" और किसी ने भी इसका जवाब नहीं दिया। सुनिश्चित करने के लिए, आप क्रमबद्ध (JSON से / सीरियल, पार्सलेबल / टू) कर सकते हैं और ऑब्जेक्ट के डेटा की एक प्रति पास कर सकते हैं और उसी डेटा वाले एक नए ऑब्जेक्ट को बनाया जा सकता है; लेकिन इसमें एक ही संदर्भ / हैंडल नहीं होगा। इसके अलावा, कई अन्य लोगों ने उल्लेख किया है कि आप संदर्भ को एक स्थिर स्टोर में संग्रहीत कर सकते हैं। और यह तब तक काम करेगा जब तक कि एंड्रॉइड आपकी गतिविधि को onDestroy करने का निर्णय नहीं लेता है।

तो, वास्तव में मूल प्रश्न को हल करने के लिए आपको एक स्थिर लुकअप की आवश्यकता होगी और साथ ही प्रत्येक वस्तु अपने संदर्भ को अपडेट करेगी जब / फिर से बनाया गया हो। उदाहरण के लिए, प्रत्येक एंड्रॉइड एक्टिविटी खुद को राहत देती है अगर उसका ऑनक्रीट कहा जाता है। आप यह भी देख सकते हैं कि कुछ लोग नाम से किसी गतिविधि को खोजने के लिए कार्य सूची का उपयोग कैसे करते हैं। (सिस्टम अस्थायी रूप से अंतरिक्ष को बचाने के लिए गतिविधि के इस उदाहरण को नष्ट कर रहा है..गतिविधायक कार्य, कार्य सूची प्रभावी रूप से प्रत्येक गतिविधि के सबसे हाल के ऑब्जेक्ट उदाहरण की एक विशेष सूची है)।

सन्दर्भ के लिए:

रोक दिया गया: "गतिविधि पूरी तरह से एक और गतिविधि द्वारा अस्पष्ट है (गतिविधि अब" पृष्ठभूमि "में है)। एक रुकी हुई गतिविधि अभी भी जीवित है ( गतिविधि ऑब्जेक्ट स्मृति में बरकरार है , यह सभी राज्य और सदस्य जानकारी रखता है, लेकिन ऐसा नहीं है विंडो मैनेजर से जुड़ी)। हालांकि, यह अब उपयोगकर्ता को दिखाई नहीं देता है और इसे सिस्टम द्वारा मारा जा सकता है जब मेमोरी को कहीं और जरूरत होती है। "

onDestroy "सिस्टम अंतरिक्ष को बचाने के लिए गतिविधि के इस उदाहरण को अस्थायी रूप से नष्ट कर रहा है।"

तो, संदेश बस एक व्यावहारिक समाधान है। यह मूल रूप से "सज़ा" देता है। वस्तुओं के संदर्भ के लिए प्रयास करने के बजाय; फिर आप SequentialCode के बजाय MessagePassing का उपयोग करने के लिए अपने डिज़ाइन को फिर से आर्किटेक्ट करते हैं। तेजी से डिबग करने के लिए कठिन; लेकिन यह आपको इस तरह के संचालन की समझ को अनदेखा करने देता है। प्रभावी रूप से, प्रत्येक ऑब्जेक्ट विधि का उपयोग उलटा होता है इसलिए कॉलर एक संदेश पोस्ट करता है और ऑब्जेक्ट स्वयं उस संदेश के लिए एक हैंडलर को परिभाषित करता है। बहुत अधिक कोड है, लेकिन यह Android OE प्रतिबंधों के साथ मजबूत बना सकता है।

यदि आप चाहते हैं कि शीर्ष गतिविधि ("संदर्भ" हर जगह आवश्यक होने के कारण एंड्रॉइड ऐप में विशिष्ट बात है), तो आप स्थैतिक वैश्विक अंतरिक्ष में "शीर्ष" के रूप में जब भी अपने onResume को कहते हैं, तब आप प्रत्येक गतिविधि सूची को "शीर्ष" के रूप में देख सकते हैं। फिर आपका AlertDialog या जो भी एक संदर्भ की जरूरत है, बस इसे वहां से हड़प सकता है। इसके अलावा, यह एक वैश्विक उपयोग करने के लिए थोड़ा भाग्यशाली है, लेकिन एक कॉन्सेप्ट को हर जगह ऊपर और नीचे से गुजरना आसान बना सकता है और, जब आप एक मैसेजबस का उपयोग करते हैं, तो यह आईटी वैसे भी वैश्विक है।


ओटो ने इसे सिर्फ एक सादे पुराने जावा ऐप में बाहरी रूप से चलाने में सक्षम है। तो, एंड्रॉइड के साथ गड़बड़ किए बिना देव और परीक्षण के लिए अच्छा है। ओटो के पास बड़ी सीखने की अवस्था है और इसमें से अधिकांश में हल पहले से ही एंड्रॉइड तरीकों (स्थानीय प्रसारण आदि) या सामान्य ऐप देव दृष्टिकोणों में हल किया गया है (आप ओटो की वैश्विक खोज की तुलना में बहुत सरल वैश्विक लेखन लिख सकते हैं, सामान्य दृष्टिकोण बहुत अधिक हैं। कोड के माध्यम से और डिबगिंग के माध्यम से कदम रखने के लिए वेक्टरिंग / एफ 3 के लिए अधिक स्वीकार्य है)।
टिमजॉर्स 2

2
  1. मुझे पता है कि स्थैतिक खराब है, लेकिन ऐसा लगता है कि हम यहां इसका उपयोग करने के लिए मजबूर हैं। Parceables / seriazables के साथ समस्या यह है कि दो गतिविधियों में एक ही वस्तु के डुप्लिकेट इंस्टेंस = मेमोरी और सीपीयू की बर्बादी होती है।

    public class IntentMailBox {
        static Queue<Object> content = new LinkedList<Object>();
    }

कॉलिंग गतिविधि

IntentMailBox.content.add(level);
Intent intent = new Intent(LevelsActivity.this, LevelActivity.class);
startActivity(intent);

कॉल की गई गतिविधि (ध्यान दें कि onCreate () और onResume () को कई बार कहा जा सकता है जब सिस्टम को नष्ट कर देता है और गतिविधियों को पुन: बनाता है)

if (IntentMailBox.content.size()>0)
    level = (Level) IntentMailBox.content.poll();
else
    // Here you reload what you have saved in onPause()
  1. दूसरा तरीका यह है कि आप जिस क्लास में जाना चाहते हैं, उसी क्लास का स्टैटिक फील्ड घोषित करें। यह केवल इस उद्देश्य के लिए काम करेगा। मत भूलो कि यह onCreate में शून्य हो सकता है, क्योंकि आपके ऐप पैकेज को सिस्टम से मेमोरी से अनलोड किया गया है और बाद में पुनः लोड किया गया है।

  2. ध्यान में रखते हुए कि आपको अभी भी गतिविधि जीवनचक्र को संभालने की आवश्यकता है, आप सभी डेटा को सीधे साझा प्राथमिकताओं में लिखना चाह सकते हैं, जो जटिल डेटा संरचनाओं के साथ दर्दनाक है।


1

जवाब लगभग सभी सही लेकिन उन लोगों के लिए ऊपर जो उन जवाब एंड्रॉयड शक्तिशाली वर्ग है समझने के नहीं करता आशय आप न केवल गतिविधि लेकिन एंड्रॉयड (broadcasr रिसीवर, सामग्री के लिए servises प्रदान का एक और घटकों के बीच डेटा साझा यह की मदद से हम ContetnResolver वर्ग कोई आशय का उपयोग )। अपनी गतिविधि में आप इरादे का निर्माण करते हैं

Intent intent = new Intent(context,SomeActivity.class);
intent.putExtra("key",value);
startActivity(intent);

आपकी प्राप्ति गतिविधि में आपके पास है

public class SomeActivity extends AppCompactActivity {

    public void onCreate(...){
    ...
          SomeObject someObject = getIntent().getExtras().getParceable("key");
    }

}

आपको गतिविधियों के बीच साझा करने के लिए अपने ऑब्जेक्ट पर पार्सएबल या सीरियल करने योग्य इंटरफ़ेस लागू करना होगा। ऑब्जेक्ट पर Serializable इंटरफ़ेस के बजाय Parcealbe को लागू करना कठिन है, इसलिए Android के लिए विशेष रूप से प्लगइन है। इसे डाउनलोड करें और इसका उपयोग करें


0

मैं हमेशा सोचता था कि यह अन्य गतिविधि के एक तरीके में कॉल करने के रूप में सरल क्यों नहीं हो सकता है। मैंने हाल ही में एक उपयोगिता पुस्तकालय लिखा है जो इसे लगभग उतना ही सरल बनाता है। आप इसे यहाँ देख सकते हैं ( https://github.com/noxiouswinter/gnlib_android/wiki/gnlauker )।

GNLauncher किसी अन्य गतिविधि आदि से किसी गतिविधि के लिए ऑब्जेक्ट / डेटा भेजना उतना आसान बनाता है जितना कि पैरामीटर में आवश्यक डेटा के साथ tha गतिविधि में एक फ़ंक्शन को कॉल करना। यह प्रकार की सुरक्षा का परिचय देता है और स्ट्रिंग कुंजी का उपयोग करके इरादे के साथ संलग्न करने और दूसरे छोर पर उसी को पूर्ववत करने के सभी चरणों को हटा देता है।

प्रयोग

लॉन्च करने के लिए गतिविधि पर कॉल करने के तरीकों के साथ एक इंटरफ़ेस को परिभाषित करें।

public interface IPayload {
    public void sayHello(String name, int age);
}

में शुरू करने के लिए गतिविधि पर उपरोक्त इंटरफ़ेस लागू करें। गतिविधि के तैयार होने पर GNLauncher को भी सूचित करें।

public class Activity_1 extends Activity implements IPayload {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //Notify GNLauncher when the Activity is ready. 
        GNLauncher.get().ping(this);
    }

    @Override
    public void sayHello(String name, int age) {
        Log.d("gnlib_test", "Hello " + name + "! \nYour age is: " + age);
    }
}

अन्य गतिविधि में, उपरोक्त गतिविधि के लिए एक प्रॉक्सी प्राप्त करें और वांछित मापदंडों के साथ किसी भी विधि को कॉल करें।

public class Activity_2 extends Activity {
    public void onClick(View v) {
        ((IPayload)GNLauncher.get().getProxy(this, IPayload.class, Activity_1.class)).sayHello(name, age);
    }
}

पहली गतिविधि लॉन्च की जाएगी और आवश्यक मापदंडों के साथ विधि को बुलाया जाएगा।

आवश्यक शर्तें

निर्भरता कैसे जोड़े के बारे में जानकारी के लिए कृपया https://github.com/noxiouswinter/gnlib_android/wiki#prerequisites देखें ।


0

एक गतिविधि से दूसरी गतिविधि पर ऑब्जेक्ट पास करें।

(1) स्रोत गतिविधि

Intent ii = new Intent(examreport_select.this,
                    BarChartActivity.class);

            ii.putExtra("IntentExamResultDetail",
                    (Serializable) your List<ArraList<String>> object here);
            startActivity(ii);

(२) डेस्टिनेशन एक्यूटिविटी

List<ArrayList<String>> aa = (List<ArrayList<String>>) getIntent()
            .getSerializableExtra("IntentExamResultDetail");

0

मैं हस्तांतरण करने के लिए Pacelable या Serializable के साथ ऑब्जेक्ट सेट करता था, लेकिन जब भी मैं ऑब्जेक्ट (मॉडल) में अन्य चर जोड़ता हूं, तो मुझे यह सब पंजीकृत करना होगा। यह बहुत नाकाफी है।

गतिविधियों या टुकड़ों के बीच वस्तु को स्थानांतरित करना सुपर आसान है।

Android DataCache


0

हम वस्तु को एक गतिविधि से दूसरी गतिविधि में पास कर सकते हैं:

SupplierDetails poSuppliersDetails = new SupplierDetails();

अंदर poSuppliersDetailsहमारे कुछ मूल्य हैं। अब मैं इस वस्तु को लक्ष्य गतिविधि के लिए भेज रहा हूँ:

Intent iPODetails = new Intent(ActivityOne.this, ActivityTwo.class);
iPODetails.putExtra("poSuppliersDetails", poSuppliersDetails);

ACtivityTwo में इसे कैसे प्राप्त करें:

private SupplierDetails supplierDetails;
    supplierDetails =(SupplierDetails) getIntent().getSerializableExtra("poSuppliersDetails");


-1

सभी को नमस्कार, मुझे बहुत सारे अच्छे विकल्प दिखाई दे रहे हैं लेकिन मैं सोच रहा था कि बाइंडिंग का उपयोग क्यों नहीं किया गया है?

किसी वस्तु के संदर्भ को पास करना मेरे लिए वस्तुओं को क्रमबद्ध और नष्ट करने की तुलना में अधिक कुशल लगता है, लेकिन मैंने यह देखने के लिए कोई गहरा गोता नहीं लगाया है कि पर्दे के पीछे क्या चल रहा है।

बाइंडर बनाना काफी सरल है ...

public class MyBinder extends Binder {

    private Object myObject;

    public MyBinder(Object object) {
        myObject = object;
    }

    public Object getObject() {
        return myObject;
    }

}

और इसका उपयोग करने के लिए पार्सल बनाने से वह खराब ईथर नहीं है।

public class MyParcelable implements Parcelable {

    private Object myObject;

    public MyParcelable() {
    }

    public MyParcelable(Parcel parcel) {
        myObject = ((MyBinder)parcel.readStrongBinder()).getObject();
    }

    public void setObject(Object object) {
        myObject = object;
    }

    public Object getObject() {
        return myObject;
    }

    public void writeToParcel(Parcel parcel, int flags) {
        parcel.writeStrongBinder(new MyBinder(myObject));
    }

    public int describeContents() {
        return myObject == null ? 0 : 1;
    }

    public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>() {

        public MyParcelable createFromParcel(Parcel parcel) {
            return new MyParcelable(parcel);
        }

        public MyParcelable[] newArray(int length) {
            return new MyParcelable[length];
        }

    };
}

यह तर्क वास्तव में अच्छा है क्योंकि आप वास्तव में गतिविधि से गतिविधि तक एक संदर्भ दे रहे हैं।

मैं nulls के लिए जाँच करने की सलाह दूंगा और अगर Instof Binder MyBinder है!

और इसे लागू करने के लिए आप बस ...

इसे भेज दो

Object myObject = "some object";
MyParcelable myParcelable = new MyParcelable();
myParcelable.setObject(myObject);

intent.putExtra("MyParcelable", myParcelable);

वापस लाओ

myParcelable = (MyParcelable) getIntent().getExtras().getParcelable("MyParcelable");
myObject = myParcelable.getObject();

बिल्ली किसी को सभी पागल हो सकता है और इस चूसने वाला एक सच्चा सामान्य बना सकता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.