Come inviare un oggetto da un'attività Android a un'altra usando Intents?


849

Come posso passare un oggetto di un tipo personalizzato da un'attività all'altra utilizzando il putExtra()metodo della classe intenti ?


@UMMA: non è necessario continuare a contrassegnare le domande come "Wiki della community". Dai
Dave Webb,

1
@Paresh: il link che hai fornito è rotto. potresti fornire un'alternativa?
antiplex


Dai un'occhiata a questa risposta. stackoverflow.com/questions/8857546/…
Heitor Colangelo,

ho trovato un semplice ed elegante metodo stackoverflow.com/a/37774966/6456129
Yessy

Risposte:


751

Se stai solo passando oggetti in giro, Parcelable è stato progettato per questo. Richiede un piccolo sforzo in più rispetto all'utilizzo della serializzazione nativa di Java, ma è molto più veloce (e intendo molto, MODO più veloce).

Dai documenti, un semplice esempio di come implementare è:

// simple class that just has one member property as an example
public class MyParcelable implements Parcelable {
    private int mData;

    /* everything below here is for implementing Parcelable */

    // 99.9% of the time you can just ignore this
    @Override
    public int describeContents() {
        return 0;
    }

    // write your object's data to the passed-in Parcel
    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(mData);
    }

    // this is used to regenerate your object. All Parcelables must have a CREATOR that implements these two methods
    public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>() {
        public MyParcelable createFromParcel(Parcel in) {
            return new MyParcelable(in);
        }

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

    // example constructor that takes a Parcel and gives you an object populated with it's values
    private MyParcelable(Parcel in) {
        mData = in.readInt();
    }
}

Ricorda che nel caso in cui tu abbia più di un campo da recuperare da un determinato Pacco, devi farlo nello stesso ordine in cui li hai inseriti (cioè in un approccio FIFO).

Una volta che hai implementato i tuoi oggetti Parcelableè solo una questione di metterli nei tuoi Intenti con putExtra () :

Intent i = new Intent();
i.putExtra("name_of_extra", myParcelableObject);

Quindi puoi estrarli di nuovo con getParcelableExtra () :

Intent i = getIntent();
MyParcelable myParcelableObject = (MyParcelable) i.getParcelableExtra("name_of_extra");

Se la tua classe di oggetti implementa Parcelable e Serializable, assicurati di eseguire il cast su uno dei seguenti:

i.putExtra("parcelable_extra", (Parcelable) myParcelableObject);
i.putExtra("serializable_extra", (Serializable) myParcelableObject);

14
Come verrebbe implementato laddove mData è un oggetto (ad es. JSONObject) e non un int?
Peter Ajtai,

301
Perché non si può semplicemente passare l'oggetto senza tutto questo? Vogliamo passare un oggetto che è già in memoria.
Ceklock

110
@tecnotron le sue app perché sono in processi diversi e hanno spazi di indirizzi di memoria separati, non puoi semplicemente inviare il puntatore (riferimento) al blocco di memoria nel tuo processo e ti aspetti che sia disponibile in un altro processo.
marcinj,

12
Cosa devo fare se non riesco a rendere la classe dell'oggetto serializzabile o Parceable?
Amel Jose,

11
@ceklock il motivo dietro questo è il seguente: Quando l'attività va indietro e successivamente viene uccisa dalla memoria, e quindi quando l'utente la apre dal menu recenti, deve creare l'attività da dove era stata interrotta. Deve essere la stessa UI. In questo caso, l'oggetto non è in memoria. Ma l'intento è.
tasomaniaco

194

Dovrai serializzare il tuo oggetto in una sorta di rappresentazione di stringa. Una possibile rappresentazione di stringa è JSON e uno dei modi più semplici per serializzare da / a JSON su Android, se me lo chiedi, è tramite Google GSON .

In tal caso, basta inserire il valore di ritorno della stringa da (new Gson()).toJson(myObject);e recuperare il valore della stringa e utilizzarlo fromJsonper ripristinarlo nel proprio oggetto.

Se il tuo oggetto non è molto complesso, tuttavia, potrebbe non valere il sovraccarico e potresti invece considerare di passare i valori separati dell'oggetto.


19
Immagino perché la risposta di fiXedd risolve lo stesso problema senza l'uso di librerie esterne, in un modo semplicemente così preferibile, che nessuno dovrebbe mai avere un motivo per scegliere la soluzione che ho fornito (inconsapevole, al momento, di la brillante soluzione di fiXedd)
David Hedlund,

5
Penso sia corretto. Inoltre, JSON è un protocollo più appropriato per client / server e non thread-to-thread.
mobibob,

16
Non necessariamente una cattiva idea, esp. poiché Gson è molto più semplice da utilizzare rispetto all'implementazione di pacchetti per tutti gli oggetti che si desidera inviare.
uvesten,

7
come iam usando gson nella mia app questo è un modo davvero semplice e carino!
Lars,

16
Bella risposta, anche se la soluzione completa sarebbe String s = (new Gson().toJson(client));e poiCli client = new Gson().fromJson(s, Cli.class);
Joaquin Iurchuk il

155

È possibile inviare oggetti serializzabili tramite intento

// send where details is object
ClassName details = new ClassName();
Intent i = new Intent(context, EditActivity.class);
i.putExtra("Editing", details);
startActivity(i);


//receive
ClassName model = (ClassName) getIntent().getSerializableExtra("Editing");

And 

Class ClassName implements Serializable {
} 

2
puoi anche inviare oggetti Parcelable per intento.
tony gil,

6
"Serializable è comicamente lento su Android. In molti casi borderline inutile." guarda stackoverflow.com/questions/5550670/…
Seraphim's

cosa succede se l'attività è già in esecuzione, è necessario eseguire startActivity (i); ? Voglio dire, posso fare l' attività A chiamare l' attività B e ciò restituisce i dati all'attività A ? sono confuso?
Francisco Corrales Morales,

3
Le prestazioni di @ Seraphim sono importanti se stai serializzando molti oggetti, ma l'utente non noterà se la serializzazione di un oggetto richiede 1 ms o 10 ms. Se un extra intento è già Serializablema non Parcelable, raramente vale la seccatura per farlo Parcelable.
Kevin Krumwiede,

67

Per situazioni in cui sai che passerai i dati all'interno di un'applicazione, usa "globali" (come le Classi statiche)

Ecco cosa Dianne Hackborn (hackbod - un ingegnere del software Android di Google) in merito:

Per situazioni in cui sai che le attività sono in esecuzione nello stesso processo, puoi semplicemente condividere i dati attraverso i globi. Ad esempio, potresti avere un globale HashMap<String, WeakReference<MyInterpreterState>> e quando crei un nuovo MyInterpreterState trovi un nome univoco per esso e lo metti nella mappa hash; per inviare quello stato a un'altra attività, è sufficiente inserire il nome univoco nella mappa hash e quando viene avviata la seconda attività, è possibile recuperare MyInterpreterState dalla mappa hash con il nome che riceve.


25
Sì, ho trovato strano che ci venissero dati questi Intenti da usare, e poi un ingegnere di alto livello ci dice di usare solo i globuli per i nostri dati. Ma eccolo direttamente dalla bocca dei cavalli.
Richard Le Mesurier,

1
La debole rifrazione qui non sarebbe vittima della raccolta dei rifiuti?
ulysseus,

1
@uLYsseus pensa che sia l'idea, una volta che hai finito con loro nelle attività ... quindi quando le attività rilevanti vengono distrutte, glielo permetterà di farlo
Peter Ajtai,

1
@RichardLeMesurier Stavo pensando la stessa cosa, ma poi ho esaminato il post di Google Gruppi di Dianne Hackborn sopra menzionato, e lei afferma che l'unico problema con i globali sarebbe quando si usano intenti impliciti (che possono avviare un'attività al di fuori del pacchetto) ). Questo ha senso, come afferma Dianne, perché quelle attività avrebbero molto probabilmente una conoscenza zero dei tipi personalizzati che stai passando a loro. Una volta che l'ho letto, mi ha reso più chiaro il motivo per cui i globi potrebbero non essere una cattiva strada in queste circostanze, e ho pensato di condividere nel caso in cui anche altri fossero curiosi
BMB

gli intenti erano troppo ingegnerizzati al punto da poter essere passati a un altro computer. che ovviamente non è un buon modo per fare qualcosa quando in realtà hai solo un processo in cui ti stai divertendo. Ragioni per cui non è buono: uso della memoria, uso della cpu, uso della batteria. l'ultimo, in particolare, ha fatto le scelte progettuali con intenzioni piuttosto perplesse col senno di poi. ci sono persone che insistono sul fatto che sono una buona idea, di solito perché "google lo ha detto".
Lassi Kinnunen,

49

La tua classe dovrebbe implementare Serializable o Parcelable.

public class MY_CLASS implements Serializable

Una volta fatto puoi inviare un oggetto su putExtra

intent.putExtra("KEY", MY_CLASS_instance);

startActivity(intent);

Per ottenere extra devi solo fare

Intent intent = getIntent();
MY_CLASS class = (MY_CLASS) intent.getExtras().getSerializable("KEY");

Se la tua classe implementa Parcelable, usa successivamente

MY_CLASS class = (MY_CLASS) intent.getExtras().getParcelable("KEY");

Spero che sia d'aiuto: D


6
La tua classe deve implementare Serializableè sbagliata. La classe può implementare Parcelablead esempio.
Marc Plano-Lesay,

qual è la differenza tra Parcelable e Serializable @Kernald? in termini di tempo di elaborazione è più lenta / non buona pratica o qualcosa del genere?
Gumuruh,

Mentre Serializableè un'interfaccia Java standard, Parcelableè specifica per Android. In termini di prestazioni, Parcelable è più efficiente: developerphil.com/parcelable-vs-serializable
Marc Plano-Lesay,

35

Risposta breve per necessità veloce

1. Implementa la tua classe su serializzabile.

Se hai delle classi interne, non dimenticare di implementarle anche su Serializable !!

public class SportsData implements  Serializable
public class Sport implements  Serializable

List<Sport> clickedObj;

2. Metti il ​​tuo oggetto in Intento

 Intent intent = new Intent(SportsAct.this, SportSubAct.class);
            intent.putExtra("sport", clickedObj);
            startActivity(intent);

3. E ricevi il tuo oggetto nell'altra Classe di attività

Intent intent = getIntent();
    Sport cust = (Sport) intent.getSerializableExtra("sport");


Puoi ottenere lo stesso risultato implementando l'interfaccia Parcelable. L'interfaccia parcelable richiede più tempo per essere implementata rispetto a Serializable a causa delle dimensioni del codice. Ma funziona più velocemente di Serializable e usa meno risorse.
Kwnstantinos Nikoloutsos il

27

se la tua classe di oggetti implementa Serializable, non devi fare nient'altro, puoi passare un oggetto serializzabile.
questo è quello che uso.


24

implementare serializzabile nella tua classe

public class Place implements Serializable{
        private int id;
        private String name;

        public void setId(int id) {
           this.id = id;
        }
        public int getId() {
           return id;
        }
        public String getName() {
           return name;
        }

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

Quindi puoi passare questo oggetto con intenzione

     Intent intent = new Intent(this, SecondAct.class);
     intent.putExtra("PLACE", Place);
     startActivity(intent);

nella seconda attività è possibile ottenere dati come questo

     Place place= (Place) getIntent().getSerializableExtra("PLACE");

Ma quando i dati diventano grandi, questo metodo sarà lento.


16

Puoi usare Android BUNDLE per farlo.

Crea un pacchetto dalla tua classe come:

public Bundle toBundle() {
    Bundle b = new Bundle();
    b.putString("SomeKey", "SomeValue");

    return b;
}

Quindi passare questo pacchetto con INTENT. Ora puoi ricreare il tuo oggetto classe passando come bundle

public CustomClass(Context _context, Bundle b) {
    context = _context;
    classMember = b.getString("SomeKey");
}

Dichiaralo nella tua classe personalizzata e utilizzalo.


1
Preferibile a dirigere l'implementazione di Parcelable, IMHO. Il pacchetto implementa Parcelable da solo in modo da avere ancora il vantaggio in termini di prestazioni, evitando tutti i problemi di implementazione da soli. Invece, puoi usare le coppie chiave-valore per archiviare e recuperare i dati che sono di gran lunga più robusti che affidarsi al semplice ordine.
Risadinha,

Parcelable mi sembra complicato, nella mia risposta sopra sto usando il metodo toBundle dalla classe sul suo oggetto, quindi l'oggetto viene convertito in bundle e quindi possiamo usare il costruttore per convertire il bundle in oggetto class.
om252345,

Questa soluzione è praticabile solo se si passa un singolo oggetto attraverso un intento.
TheIT

Come JSON, ma JSON è leggero, penso.
David,

L'oggetto quando lo recupererò sarà lo stesso oggetto o una copia?
Markus,

16

Esistono due modi in cui è possibile accedere a variabili o oggetti in altre classi o attività.

A. Database

B. preferenze condivise.

C. serializzazione degli oggetti.

D. Una classe che può contenere dati comuni può essere denominata Common Utilities, dipende da te.

E. Trasmissione dei dati tramite Intents and Parcelable Interface.

Dipende dalle esigenze del tuo progetto.

UN. Database

SQLite è un database open source incorporato in Android. SQLite supporta le funzionalità standard del database relazionale come la sintassi SQL, le transazioni e le istruzioni preparate.

Tutorial - http://www.vogella.com/articles/AndroidSQLite/article.html

B. Preferenze condivise

Supponiamo di voler memorizzare il nome utente. Quindi ora ci saranno due cose: un nome utente chiave , un valore valore.

Come conservare

 // Create an 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();

Usando putString (), putBoolean (), putInt (), putFloat (), putLong () è possibile salvare il tipo desiderato.

Come andare a prendere

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

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

C. Serializzazione degli oggetti

La serializzazione degli oggetti viene utilizzata se si desidera salvare uno stato dell'oggetto per inviarlo sulla rete o è possibile utilizzarlo anche per i propri scopi.

Usa i java bean e conservali come uno dei suoi campi e usa getter e setter per quello

JavaBeans sono classi Java che hanno proprietà. Pensa alle proprietà come variabili di istanza private. Dal momento che sono privati, l'unico modo in cui è possibile accedervi dall'esterno della loro classe è attraverso i metodi nella classe. I metodi che modificano il valore di una proprietà sono chiamati metodi setter e i metodi che recuperano il valore di una proprietà sono chiamati metodi getter.

public class VariableStorage implements Serializable  {

    private String inString ;

    public String getInString() {
        return inString;
    }

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


}

Impostare la variabile nel metodo di posta utilizzando

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

Quindi utilizzare Serialzation oggetto per serializzare questo oggetto e nell'altra classe deserializzare questo oggetto.

Nella serializzazione, un oggetto può essere rappresentato come una sequenza di byte che include i dati dell'oggetto, nonché informazioni sul tipo di oggetto e sui tipi di dati memorizzati nell'oggetto.

Dopo che un oggetto serializzato è stato scritto in un file, può essere letto dal file e deserializzato, ovvero le informazioni sul tipo e i byte che rappresentano l'oggetto e i suoi dati possono essere utilizzati per ricreare l'oggetto in memoria.

Se vuoi un tutorial per questo fare riferimento a questo link

http://javawithswaranga.blogspot.in/2011/08/serialization-in-java.html

Ottieni variabili in altre classi

D. Common Utilità

Puoi creare una classe da solo che può contenere dati comuni di cui hai spesso bisogno nel tuo progetto.

Campione

public class CommonUtilities {

    public static String className = "CommonUtilities";

}

E. Trasmissione dei dati attraverso gli intenti

Fare riferimento a questo tutorial per questa opzione di passaggio dei dati.

http://shri.blog.kraya.co.uk/2010/04/26/android-parcel-data-to-pass-between-activities-using-parcelable-classes/


Buon tutorial che menzioni in (E) sul passaggio di dati attraverso Intents.
riscrivere il

15

Grazie per l'aiuto parcelable ma ho trovato un'altra soluzione opzionale

 public class getsetclass implements Serializable {
        private int dt = 10;
    //pass any object, drwabale 
        public int getDt() {
            return dt;
        }

        public void setDt(int dt) {
            this.dt = dt;
        }
    }

Nell'attività 1

getsetclass d = new getsetclass ();
                d.setDt(50);
                LinkedHashMap<String, Object> obj = new LinkedHashMap<String, Object>();
                obj.put("hashmapkey", d);
            Intent inew = new Intent(SgParceLableSampelActivity.this,
                    ActivityNext.class);
            Bundle b = new Bundle();
            b.putSerializable("bundleobj", obj);
            inew.putExtras(b);
            startActivity(inew);

Ottieni dati nell'attività 2

 try {  setContentView(R.layout.main);
            Bundle bn = new Bundle();
            bn = getIntent().getExtras();
            HashMap<String, Object> getobj = new HashMap<String, Object>();
            getobj = (HashMap<String, Object>) bn.getSerializable("bundleobj");
            getsetclass  d = (getsetclass) getobj.get("hashmapkey");
        } catch (Exception e) {
            Log.e("Err", e.getMessage());
        }

1
buona risposta, ma aumenta i tuoi standard di codifica ... +1 però per aver portato Serializable nella competizione, tuttavia i Parcellables sono molto più veloci ...
Tra

13

Uso Gson con la sua API così potente e semplice per inviare oggetti tra attività,

Esempio

// This is the object to be sent, can be any object
public class AndroidPacket {

    public String CustomerName;

   //constructor
   public AndroidPacket(String cName){
       CustomerName = cName;
   }   
   // other fields ....


    // You can add those functions as LiveTemplate !
    public String toJson() {
        Gson gson = new Gson();
        return gson.toJson(this);
    }

    public static AndroidPacket fromJson(String json) {
        Gson gson = new Gson();
        return gson.fromJson(json, AndroidPacket.class);
    }
}

2 funzioni le aggiungi agli oggetti che vuoi inviare

uso

Invia oggetto da A a B

    // Convert the object to string using Gson
    AndroidPacket androidPacket = new AndroidPacket("Ahmad");
    String objAsJson = androidPacket.toJson();

    Intent intent = new Intent(A.this, B.class);
    intent.putExtra("my_obj", objAsJson);
    startActivity(intent);

Ricevi in ​​B

@Override
protected void onCreate(Bundle savedInstanceState) {        
    Bundle bundle = getIntent().getExtras();
    String objAsJson = bundle.getString("my_obj");
    AndroidPacket androidPacket = AndroidPacket.fromJson(objAsJson);

    // Here you can use your Object
    Log.d("Gson", androidPacket.CustomerName);
}

Lo uso quasi in ogni progetto che faccio e non ho problemi di prestazioni.


Grazie, questo mi ha risparmiato ore di complicazioni eccessive.
Hristo Stoyanov,

10

Ho lottato con lo stesso problema. L'ho risolto utilizzando una classe statica, memorizzando tutti i dati desiderati in una HashMap. In cima uso un'estensione della classe Activity standard in cui ho scavalcato i metodi onCreare un onDestroy per fare il trasporto e la cancellazione dei dati nascosti. Alcune impostazioni ridicole devono essere modificate, ad esempio la gestione dell'orientamento.

Annotazione: non fornire oggetti generali da passare a un'altra Attività è dolore nel culo. È come spararsi al ginocchio e sperare di vincere 100 metri. "Parcable" non è un sostituto sufficiente. Mi fa ridere ... Non voglio implementare questa interfaccia per la mia API priva di tecnologia, in quanto meno voglio introdurre un nuovo livello ... Come potrebbe essere, che siamo nella programmazione mobile così lontani da paradigma moderno ...


9

Nella tua prima attività:

intent.putExtra("myTag", yourObject);

E nel tuo secondo:

myCustomObject myObject = (myCustomObject) getIntent().getSerializableExtra("myTag");

Non dimenticare di rendere serializzabile l'oggetto personalizzato:

public class myCustomObject implements Serializable {
...
}

Parcelable è meglio di Serializable! Evita di usare Serializable nel tuo codice Android!
Filipe Brito,

7

Un altro modo per farlo è usare l' Applicationoggetto (android.app.Application). Lo definisci nel tuo AndroidManifest.xmlfile come:

<application
    android:name=".MyApplication"
    ...

È quindi possibile chiamare questo da qualsiasi attività e salvare l'oggetto nella Applicationclasse.

In FirstActivity:

MyObject myObject = new MyObject();
MyApplication app = (MyApplication) getApplication();
app.setMyObject(myObject);

In SecondActivity, esegui:

MyApplication app = (MyApplication) getApplication();
MyObject retrievedObject = app.getMyObject(myObject);

Ciò è utile se si hanno oggetti con ambito a livello di applicazione, ad esempio devono essere utilizzati in tutta l'applicazione. IlParcelable metodo è ancora migliore se si desidera un controllo esplicito sull'ambito dell'oggetto o se l'ambito è limitato.

Questo evita comunque l'uso del Intentstutto. Non so se ti stanno bene. Un altro modo in cui l'ho usato è avere intidentificatori di oggetti inviati attraverso gli intenti e recuperare oggetti che ho in Maps Applicationnell'oggetto.


1
Non è il modo giusto di fare le cose poiché gli oggetti possono essere variabili, i tuoi possono funzionare se parli di oggetti statici lungo il ciclo di vita dell'app, ma a volte abbiamo bisogno di oggetti passi che possono essere generati usando webservice o stackoverflow.com / a / 2736612/716865
Muhannad A.Alhariri,

L'ho usato con successo con oggetti generati da webservices avendo un ambito di applicazione in Mapcui gli oggetti sono memorizzati e recuperati usando un identificatore. L'unico vero problema con questo approccio è che Android cancella la memoria dopo un po ', quindi devi controllare la presenza di null sul tuo onResume (penso che gli oggetti passati negli intenti siano persistenti ma non ne sono sicuro). A parte questo, non lo considero significativamente inferiore.
Saad Farooq,

Questa è la risposta migliore Mostra come diverse attività possono fare riferimento allo stesso modello di dati. Mi ci è voluto molto per scoprirlo!
Markus,

6

nel modello di classe (oggetto) implementare Serializable, ad esempio:

public class MensajesProveedor implements Serializable {

    private int idProveedor;


    public MensajesProveedor() {
    }

    public int getIdProveedor() {
        return idProveedor;
    }

    public void setIdProveedor(int idProveedor) {
        this.idProveedor = idProveedor;
    }


}

e la tua prima attività

MensajeProveedor mp = new MensajeProveedor();
Intent i = new Intent(getApplicationContext(), NewActivity.class);
                i.putExtra("mensajes",mp);
                startActivity(i);

e la tua seconda attività (NewActivity)

        MensajesProveedor  mensajes = (MensajesProveedor)getIntent().getExtras().getSerializable("mensajes");

in bocca al lupo!!


6
public class SharedBooking implements Parcelable{

    public int account_id;
    public Double betrag;
    public Double betrag_effected;
    public int taxType;
    public int tax;
    public String postingText;

    public SharedBooking() {
        account_id = 0;
        betrag = 0.0;
        betrag_effected = 0.0;
        taxType = 0;
        tax = 0;
        postingText = "";
    }

    public SharedBooking(Parcel in) {
        account_id = in.readInt();
        betrag = in.readDouble();
        betrag_effected = in.readDouble();
        taxType = in.readInt();
        tax = in.readInt();
        postingText = in.readString();
    }

    public int getAccount_id() {
        return account_id;
    }
    public void setAccount_id(int account_id) {
        this.account_id = account_id;
    }
    public Double getBetrag() {
        return betrag;
    }
    public void setBetrag(Double betrag) {
        this.betrag = betrag;
    }
    public Double getBetrag_effected() {
        return betrag_effected;
    }
    public void setBetrag_effected(Double betrag_effected) {
        this.betrag_effected = betrag_effected;
    }
    public int getTaxType() {
        return taxType;
    }
    public void setTaxType(int taxType) {
        this.taxType = taxType;
    }
    public int getTax() {
        return tax;
    }
    public void setTax(int tax) {
        this.tax = tax;
    }
    public String getPostingText() {
        return postingText;
    }
    public void setPostingText(String postingText) {
        this.postingText = postingText;
    }
    public int describeContents() {
        // TODO Auto-generated method stub
        return 0;
    }
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(account_id);
        dest.writeDouble(betrag);
        dest.writeDouble(betrag_effected);
        dest.writeInt(taxType);
        dest.writeInt(tax);
        dest.writeString(postingText);

    }

    public static final Parcelable.Creator<SharedBooking> CREATOR = new Parcelable.Creator<SharedBooking>()
    {
        public SharedBooking createFromParcel(Parcel in)
        {
            return new SharedBooking(in);
        }
        public SharedBooking[] newArray(int size)
        {
            return new SharedBooking[size];
        }
    };

}

Passando i dati:

Intent intent = new Intent(getApplicationContext(),YourActivity.class);
Bundle bundle = new Bundle();
i.putParcelableArrayListExtra("data", (ArrayList<? extends Parcelable>) dataList);
intent.putExtras(bundle);
startActivity(intent);

Recupero dei dati:

Bundle bundle = getIntent().getExtras();
dataList2 = getIntent().getExtras().getParcelableArrayList("data");

5

la soluzione più semplice che ho trovato è ... creare una classe con membri di dati statici con setter getter.

impostare da un'attività e ottenere da un'altra attività quell'oggetto.

attività A

mytestclass.staticfunctionSet("","",""..etc.);

attività b

mytestclass obj= mytestclass.staticfunctionGet();

1
o creato una classe serializzabile per passare a un'altra attività qualunque cosa tu voglia passare.
UMAR

9
Ricorda solo di non mettere grossi oggetti grassi. La durata di quell'oggetto sarà la stessa della durata dell'applicazione. E mai e poi mai archiviare le visualizzazioni. Questo metodo garantisce anche perdite di memoria.
Reno,

1
Questa risposta è utile ma non è una soluzione migliore in termini di memoria e ottimizzazione delle risorse
Atul Bhardwaj,

1
Ciò infrange i principi OOP introducendo variabili globali. Non si sa mai, in quale stato si trovino, se sono impostati o no, sono utilizzati da molti thread e devi affrontare questa complessità. Di solito è una buona perdita di memoria, perché non sai nemmeno quando liberare queste variabili. Per non dire che introduce un accoppiamento diretto diretto tra i diversi moduli dell'applicazione.
Africano,

2
WTF? Le altre due risposte sono molto superiori.
IcyFlame,

4

puoi usare i metodi putExtra (Serializable ..) e getSerializableExtra () per passare e recuperare oggetti del tuo tipo di classe; dovrai contrassegnare la tua classe serializzabile e assicurarti che anche tutte le variabili del tuo membro siano serializzabili ...


4

Crea applicazione Android

File >> Nuovo >> Applicazione Android

Immettere il nome del progetto: android-pass-object-to-activity

Pakcage: com.hmkcode.android

Mantieni altre selezioni predefinite, vai su Avanti fino a raggiungere Fine

Prima di iniziare a creare l'app, dobbiamo creare la classe POJO "Person" che useremo per inviare l'oggetto da un'attività all'altra. Si noti che la classe sta implementando l'interfaccia serializzabile.

Person.java

package com.hmkcode.android;
import java.io.Serializable;

public class Person implements Serializable{

    private static final long serialVersionUID = 1L;

    private String name;
    private int age;

        // getters & setters....

    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }   
}

Due layout per due attività

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
    <TextView
        android:id="@+id/tvName"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:gravity="center_horizontal"
        android:text="Name" />

    <EditText
        android:id="@+id/etName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"

        android:ems="10" >
        <requestFocus />
    </EditText>
</LinearLayout>

<LinearLayout
     android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
<TextView
    android:id="@+id/tvAge"
    android:layout_width="100dp"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:gravity="center_horizontal"
    android:text="Age" />
<EditText
    android:id="@+id/etAge"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:ems="10" />
</LinearLayout>

<Button
    android:id="@+id/btnPassObject"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:text="Pass Object to Another Activity" />

</LinearLayout>

activity_another.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
 >

<TextView
    android:id="@+id/tvPerson"
    android:layout_height="wrap_content"
    android:layout_width="fill_parent"
    android:layout_gravity="center"
    android:gravity="center_horizontal"
 />

</LinearLayout>

Due classi di attività

1) ActivityMain.java

package com.hmkcode.android;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

public class MainActivity extends Activity implements OnClickListener {

Button btnPassObject;
EditText etName, etAge;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    btnPassObject = (Button) findViewById(R.id.btnPassObject);
    etName = (EditText) findViewById(R.id.etName);
    etAge = (EditText) findViewById(R.id.etAge);

    btnPassObject.setOnClickListener(this);
}

@Override
public void onClick(View view) {

    // 1. create an intent pass class name or intnet action name 
    Intent intent = new Intent("com.hmkcode.android.ANOTHER_ACTIVITY");

    // 2. create person object
    Person person = new Person();
    person.setName(etName.getText().toString());
    person.setAge(Integer.parseInt(etAge.getText().toString()));

    // 3. put person in intent data
    intent.putExtra("person", person);

    // 4. start the activity
    startActivity(intent);
}

}

2) AnotherActivity.java

package com.hmkcode.android;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;

public class AnotherActivity extends Activity {

TextView tvPerson;

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_another);

    // 1. get passed intent 
    Intent intent = getIntent();

    // 2. get person object from intent
    Person person = (Person) intent.getSerializableExtra("person");

    // 3. get reference to person textView 
    tvPerson = (TextView) findViewById(R.id.tvPerson);

    // 4. display name & age on textView 
    tvPerson.setText(person.toString());

}
}

4

Usando la libreria Gson di google puoi passare l'oggetto a un'altra attività. In realtà convertiremo l'oggetto sotto forma di stringa json e dopo il passaggio ad altre attività ci convertiremo nuovamente in oggetto come questo

Considera una classe bean come questa

 public class Example {
    private int id;
    private String name;

    public Example(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

Dobbiamo passare l'oggetto della classe Esempio

Example exampleObject=new Example(1,"hello");
String jsonString = new Gson().toJson(exampleObject);
Intent nextIntent=new Intent(this,NextActivity.class);
nextIntent.putExtra("example",jsonString );
startActivity(nextIntent);

Per la lettura è necessario eseguire l'operazione inversa in NextActivity

 Example defObject=new Example(-1,null);
    //default value to return when example is not available
    String defValue= new Gson().toJson(defObject);
    String jsonString=getIntent().getExtras().getString("example",defValue);
    //passed example object
    Example exampleObject=new Gson().fromJson(jsonString,Example .class);

Aggiungi questa dipendenza in gradi

compile 'com.google.code.gson:gson:2.6.2'

3
Intent i = new Intent();
i.putExtra("name_of_extra", myParcelableObject);
startACtivity(i);

3

So che è in ritardo, ma è molto semplice. Tutto quello che devi fare è lasciare che la tua classe implementi Serializable come

public class MyClass implements Serializable{

}

allora puoi passare a un intento come

Intent intent=......
MyClass obje=new MyClass();
intent.putExtra("someStringHere",obje);

Per ottenerlo basta chiamare

MyClass objec=(MyClass)intent.getExtra("theString");

2

Se hai una classe singleton (fx Service) che funge comunque da gateway per il tuo layer modello, può essere risolta disponendo di una variabile in quella classe con getter e setter per essa.

Nell'attività 1:

Intent intent = new Intent(getApplicationContext(), Activity2.class);
service.setSavedOrder(order);
startActivity(intent);

Nell'attività 2:

private Service service;
private Order order;

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

    service = Service.getInstance();
    order = service.getSavedOrder();
    service.setSavedOrder(null) //If you don't want to save it for the entire session of the app.
}

In servizio:

private static Service instance;

private Service()
{
    //Constructor content
}

public static Service getInstance()
{
    if(instance == null)
    {
        instance = new Service();
    }
    return instance;
}
private Order savedOrder;

public Order getSavedOrder()
{
    return savedOrder;
}

public void setSavedOrder(Order order)
{
    this.savedOrder = order;
}

Questa soluzione non richiede alcuna serializzazione o altro "packaging" dell'oggetto in questione. Ma sarà utile solo se si utilizza questo tipo di architettura comunque.


Quali sono gli svantaggi di questo approccio? Sembra così logico e sottile. Ho sempre letto che non dovresti farlo, ma non ho mai una buona spiegazione su cosa potrebbe andare storto.
Markus,

Dal momento che non posso più modificare il mio commento: non è questa l'unica soluzione possibile per ottenere un riferimento a un oggetto anziché una copia? Devo recuperare lo stesso oggetto e non una copia!
Markus,

Penso che questo sia un po 'scoraggiato a causa dell'elevato accoppiamento a cui conduce. Ma sì, per quanto posso vedere, questo approccio è il più praticabile se hai bisogno dell'oggetto reale. Come sempre in programmazione, puoi fare quello che vuoi, vuoi solo farlo con attenzione. Questa soluzione ha funzionato per me, e la preferisco dato che uso comunque quell'architettura.
Kitalda,

In realtà ho finito per estendere la classe Application e lì ho memorizzato il mio modello di dati. In Intents ho solo inoltrato l'ID degli oggetti dati che potrebbero essere utilizzati per recuperare l'oggetto originale dalla classe Application. Inoltre, la classe di applicazione estesa notifica a tutti gli oggetti che utilizzano il modello di dati se cambia tramite un concetto di listener standard. So che questo si adatta solo al mio caso in cui ho bisogno di condividere un modello di dati sull'intera applicazione, ma per quel caso sono necessari anche campi e classi perfetti e non statici!
Markus,

2

Di gran lunga il modo più semplice IMHO per pacchi oggetti. È sufficiente aggiungere un tag di annotazione sopra l'oggetto che si desidera rendere parcelable.

Un esempio dalla libreria è di seguito https://github.com/johncarl81/parceler

@Parcel
public class Example {
    String name;
    int age;

    public Example(){ /*Required empty bean constructor*/ }

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

    public String getName() { return name; }

    public int getAge() { return age; }
}

2

Per prima cosa implementa Parcelable nella tua classe. Quindi passare l'oggetto in questo modo.

SendActivity.java

ObjectA obj = new ObjectA();

// Set values etc.

Intent i = new Intent(this, MyActivity.class);
i.putExtra("com.package.ObjectA", obj);

startActivity(i);

ReceiveActivity.java

Bundle b = getIntent().getExtras();
ObjectA obj = b.getParcelable("com.package.ObjectA");

La stringa del pacchetto non è necessaria, solo la stringa deve essere la stessa in entrambe le attività

RIFERIMENTO


2

Inizia un'altra attività da questa attività passa parametri tramite Bundle Object

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

Recupera su un'altra attività (YourActivity)

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

Questo va bene per un tipo di dati di tipo semplice. Ma se vuoi trasferire dati complessi tra un'attività, devi prima serializzarli.

Qui abbiamo il modello dei dipendenti

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

    getters...
    setters...
}

Puoi utilizzare la libreria Gson fornita da Google per serializzare i dati complessi come questo

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

2

A Koltin

Aggiungi l'estensione kotlin nel tuo build.gradle.

apply plugin: 'kotlin-android-extensions'

android {
    androidExtensions {
        experimental = true
   }
}

Quindi crea la tua classe di dati in questo modo.

@Parcelize
data class Sample(val id: Int, val name: String) : Parcelable

Passa oggetto con intento

val sample = Sample(1,"naveen")

val intent = Intent(context, YourActivity::class.java)
    intent.putExtra("id", sample)
    startActivity(intent)

Ottieni oggetto con intento

val sample = intent.getParcelableExtra("id")

È ancora sperimentale?
ShadeToD,

2

Il modo più semplice e java di fare è: implementare serializzabile nella tua classe pojo / modello

Consigliato per Android per la visualizzazione delle prestazioni: rendere il modello parcelable


1

Il più semplice sarebbe usare solo quanto segue in cui l'elemento è una stringa:

intent.putextra("selected_item",item)

Per ricevere:

String name = data.getStringExtra("selected_item");

3
è solo per stringa, numero intero, ecc. ma voglio l'oggetto e usare l'oggetto statico è solo possibile.
UMAR,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.