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




15 Answers

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

स्यूडोकोड :

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

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

मैं एक ग्राहक से अपने ग्राहक वर्ग की वस्तु भेजने पर काम करने की कोशिश कर रहा हूं और इसे किसी अन्य 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 पर डेटा प्रदर्शित करना चाहता हूं।

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




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

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




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

  1. पार्ससेल योग्य कार्यान्वयन

  2. Serializable कार्यान्वित

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

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

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

इवेंट बस - शून्य बॉयलरप्लेट, सबसे तेज़ दृष्टिकोण, और हार्ड-कोडेड तारों की आवश्यकता नहीं है, लेकिन इसके लिए अतिरिक्त निर्भरता की आवश्यकता होती है (हालांकि आमतौर पर हल्के, ~ 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);

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

सौभाग्य!

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

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

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



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

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;
    }
}

अपनी वस्तुओं को इरादे में रखने के बजाय, IntentHelper का उपयोग करें:

IntentHelper.addObjectForKey(obj, "key");

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

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

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




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

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

Control.Customer = CustomerClass;

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




निम्नलिखित के रूप में अपना खुद का वर्ग 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;
    }

}

आपके onCrate() विधि में

@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 वर्ग में आप निम्न कोड का उपयोग करने के लिए neet:

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



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

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");



Crete a class like bean class and implement the Serializable interface. Then we can pass it through the intent method, for example:

intent.putExtra("class", BeanClass);

Then get it from the other activity, for example:

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



This question is also discussed in another question. Please have a look at a solution to Passing data through intent using Serializable . The main point is about using Bundle object which stores the necessary data inside Intent .

 Bundle bundle = new Bundle();

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

 intent.putExtras(bundle);

To extract values:

 Bundle bundle = new Bundle();

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

Advantage of Serializable is its simplicity. However, you should consider using Parcelable method if you need many data to be transferred, because Parcelable is specifically designed for Android and it is more efficient than Serializable . You can create Parcelable class using:

  1. an online tool - site
  2. a plugin for Android Studio - Android Parcelable code generator



Yeah, using a static object is by far the easiest way of doing this with custom non-serialisable objects.




  1. I know that static is bad, but it seems that we're forced to use it here. The problem with parceables/seriazables is that the two activities have duplicate instances of the same object = waste of memory and CPU.

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

Calling activity

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

Called activity (note that onCreate() and onResume() may be called multiple times when the system destroys and recreates activities)

if (IntentMailBox.content.size()>0)
    level = (Level) IntentMailBox.content.poll();
else
    // Here you reload what you have saved in onPause()
  1. Another way is to declare a static field of the class that you want to pass in that very class. It will serve only for this purpose. Don't forget that it can be null in onCreate, because your app package has been unloaded from memory by system and reloaded later.

  2. Bearing in mind that you still need to handle activity lifecycle, you may want to write all the data straight to shared preferences, painful with complex data structures as it is.




Pass object from one activity to another activity.

(1) source activity

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

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

(2) destination acitivity

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



We can pass the object from one activity to another activity:

SupplierDetails poSuppliersDetails = new SupplierDetails();

Inside poSuppliersDetails we have some values. Now I am sending this object to target activity:

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

How to get this in ACtivityTwo:

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



Pass one activity to another:

startActivity(new Intent(getBaseContext(),GetActivity.class).putExtra("passingkey","passingvalue"));

Get values:

String myvalue= getIntent().getExtras("passingkey");



Related

java android object android-intent android-activity