Come passare un oggetto da un'attività all'altra su Android


779

Sto cercando di lavorare per inviare un oggetto della mia classe cliente da uno Activitye visualizzarlo in un altro Activity.

Il codice per la classe cliente:

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

Voglio inviare il suo oggetto dall'uno Activityall'altro e quindi visualizzare i dati sull'altro Activity.

Come posso raggiungerlo?


1
probabilmente dovresti cambiare la risposta accettata in vista dell'opinione di massa.
Rohit Vipin Mathews,

Prima usavo l'oggetto su Pacelable o Serializable, ma ogni volta che aggiungo altre variabili, devo aggiungere tutto alle funzioni per ottenere e impostare Pacelable o Serializable. così ho fatto DataCache per il trasferimento tra attività e frammenti. github.com/kimkevin/AndroidDataCache È semplicissimo trasferire oggetti.
Kimkevin,

Risposte:


886

Un'opzione potrebbe essere quella di consentire alla tua classe personalizzata di implementare l' Serializableinterfaccia e quindi puoi passare istanze di oggetto nell'intento extra usando la putExtra(Serializable..)variante del Intent#putExtra()metodo.

Pseudocodice :

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

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

Nota: assicurarsi che ogni classe nidificata della propria classe personalizzata principale abbia implementato l'interfaccia Serializable per evitare eccezioni di serializzazione. Per esempio:

class MainClass implements Serializable {

    public MainClass() {}

    public static class ChildClass implements Serializable {

        public ChildClass() {}
    }
}

126
@OD: A mia difesa, non ho mai detto che questa fosse l'opzione migliore; OP ha appena chiesto delle alternative e io ho suggerito una. Grazie comunque.
Samuh,

83
Perché Serializable non è una buona opzione? È un'interfaccia ben nota, c'è una buona probabilità che le classi delle persone possano già implementarla (ArrayList, ad esempio, è già serializzabile). Perché dovresti cambiare i tuoi oggetti dati per aggiungere altro codice semplicemente per passarli da una classe all'altra? Sembra un cattivo design. Immagino che potrebbe esserci un certo impatto sulle prestazioni a un certo livello, ma penso che nel 99% dei casi, le persone trasmettano piccole quantità di dati e non se ne cureranno. A volte anche più semplice e portatile è meglio.
Nate,

16
@Sander: questa risposta ( stackoverflow.com/questions/2139134/… ) è sbagliata allora? Dice che Parcelable è specificamente progettato per quello scopo (e molto più veloce di Serializable). Sono confuso
Slauma,

41
Parcelablepotrebbe essere buono per la velocità, ma è complicato da implementare. Che cosa succede se hai 8 oggetti che devi passare tra le attività, ne farai una Parcelable? Avrebbe più senso usare Serializableinvece. Quando si implementa, Parcelableè necessario aggiungere molto codice alla classe e ordinare i campi in un modo molto specifico; Serializabletu no. In definitiva, penso che dipenda da quanti oggetti stai passando e da cosa stai cercando di fare.
BlackHatSamurai

15
Serializableè un'interfaccia Java standard. È sufficiente contrassegnare una classe serializzabile impiantando l'interfaccia e Java la serializzerà automaticamente in determinate situazioni. Parcelableè un'interfaccia specifica per Android in cui implementi tu stesso la serializzazione. È stato creato per essere molto più efficiente di Serializable e per aggirare alcuni problemi con lo schema di serializzazione Java predefinito
Gaurav Arora,

311

Implementa la tua classe con Serializable. Supponiamo che questa sia la tua classe di entità:

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

Stiamo inviando l'oggetto chiamato denedall'attività X all'attività Y. Da qualche parte nell'attività X;

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

Nell'attività Y stiamo ottenendo l'oggetto.

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

Questo è tutto.


1
È stato davvero utile per me. Grazie ... Ma quando si riceve l'oggetto passato, la sintassi dovrebbe essere [Deneme dene = (Deneme) i.getSerializableExtra ("sampleObject"); ] ... È ???
JibW,

1
@ MustafaGüven Ma ci sto riuscendo classCastException: java.lang.Long. Puoi spiegare perché?
Shajeel Afzal,

Non c'è alcun rapporto con la mia risposta. È una cosa molto diversa che stai ricevendo. Potresti condividere i tuoi codici?
Mustafa Güven,

1
La serializzazione è troppo lenta per i POJO di grandi dimensioni. L'uso di un bus è un modello molto migliore.
Steven Mark Ford,

1
Perché dovrei dover aggiungere (Serializable)il prefisso all'oggetto?
Alston,

123
  • L'uso di variabili statiche globali non è una buona pratica di ingegneria del software .
  • La conversione dei campi di un oggetto in tipi di dati primitivi può essere un lavoro frenetico .
  • L'uso della serializzazione è OK, ma non è efficiente in termini di prestazioni sulla piattaforma Android.
  • Parcelable è progettato specificamente per Android e dovresti usarlo. Ecco un semplice esempio: passaggio di oggetti personalizzati tra le attività Android

Puoi generare il codice parcelable per la tua classe utilizzando questo sito .


4
Cosa succede se il mio oggetto contiene un Arraylist nidificato?
Dr. aNdRO,

10
Beh, forse si dovrebbe davvero prendere `` performance '' con un granello di sale imo. Se questo ha un prezzo di implementazione Parcelable, preferirei che le mie classi POJO fossero compatibili con Android e le usassi Serializable.
VH-NZZ,

Non sono d'accordo che dovresti usare Parcelable. Un semplice modello BUS è molto più efficiente in fase di esecuzione e consente di risparmiare un sacco di tempo di sviluppo.
Steven Mark Ford,

15
Secondo questo benchmark bitbucket.org/afrishman/androidserializationtest Serializable è molto più veloce di Parcelable. Smetti di condividere questa assurdità di 5 anni su Parcelable.
Africano

7
In che modo le variabili statiche globali "non sono buone pratiche di ingegneria del software"? Puoi creare qualcosa come una cache singleton e / o una griglia di dati, quindi passare un ID o simile. Quando si passano i riferimenti in Java, si utilizzano comunque variabili statiche globali in un certo senso in quanto puntano allo stesso oggetto.
breakline il

112

Usa gson per convertire il tuo oggetto in JSON e passarlo attraverso l'intento. Nella nuova attività converti JSON in un oggetto.

Nel tuo build.gradle, aggiungi questo alle tue dipendenze

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

Nella tua attività, converti l'oggetto in json-string:

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

Nell'attività di ricezione, riconvertire la stringa json nell'oggetto originale:

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

Per Kotlin è abbastanza lo stesso

Passa i dati

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

Ricevi i dati

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

3
È eccessivo, gson è solo un tipo di serializzazione di stringhe su json, è meglio implementare Serializable o Paracable.
James Roeiter,

14
Non è necessario implementare serializzabile in ogni oggetto e in ogni progetto (perdita di tempo) se è possibile utilizzare una libreria (gson) che lo gestisce. E a proposito di overkill, ci sono telefoni dual e quadcore là fuori, possono gestire anche un elenco seguendo questa idea di risposta.
sagits

4
Consiglierei anche di usare gson perché gson può anche serializzare gli arraylist in aggiunta a quanto sopra.
nurgasemetey,

4
Questo è fantastico! Nel mio caso, sto usando una libreria che gli oggetti non implementano serializzabili o parcelable. Quindi questa è la mia unica opzione afaik
Chad Bingham

2
Questa è l'opzione "migliore". Alcune classi sono così semplici, non è necessario complicare troppo la loro implementazione implementando serializzabile
Ojonugwa Jude Ochalifu

98

Durante la chiamata di un'attività

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

In toClass.java riceve l'attività di

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

Assicurati che gli strumenti di classe cliente siano pacchi

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

Adhavan, ho una domanda. Quando si crea la prima classe Intent, si passa daClass.this come primo argomento. C'è un modo per recuperare questo oggetto nella classe di attività di ricezione?
Newman,

1
Miliu, fromClass fr = (fromClass) getParent (); è questo ciò di cui hai bisogno?
Annunci,

Adhava, in realtà l'ho fatto, ma fr è nullo. Qualche idea sul perché?
Newman,

miliu, ti preghiamo di condividere la tua traccia delle eccezioni in modo che possiamo esaminarla.
Annunci,

Parcelable ha un sacco di codice della piastra della caldaia non necessario ed è francamente una perdita di tempo. Piuttosto usa un bus. Vedi il mio post qui sotto.
Steven Mark Ford,

89

Nella mia esperienza ci sono tre soluzioni principali, ognuna con i suoi svantaggi e vantaggi:

  1. Implementazione del pacco

  2. Implementazione serializzabile

  3. Utilizzando una libreria di bus di eventi leggera di qualche tipo (ad esempio, EventBus di Greenrobot o Otto di Square)

Parcelable - veloce e standard Android, ma ha un sacco di codice boilerplate e richiede stringhe codificate per riferimento quando si estraggono valori dall'intento (non fortemente tipizzati).

Serializzabile - vicino a zero boilerplate, ma è l'approccio più lento e richiede anche stringhe codificate quando si estraggono i valori dall'intento (non fortemente tipizzati).

Bus eventi : zero boilerplate, approccio più rapido e non richiede stringhe codificate, ma richiede una dipendenza aggiuntiva (sebbene di solito leggera, ~ 40 KB)

Ho pubblicato un confronto molto dettagliato su questi tre approcci, inclusi i parametri di efficienza.


4
Il link all'articolo è morto. Ancora disponibile su webarchive: web.archive.org/web/20160917213123/http://…
OlivierH

È un peccato che il collegamento non sia
attivo

Il problema dell'utilizzo del bus eventi è quando l'attività di destinazione viene ricreata a causa della rotazione, ad esempio. In questo caso, l'attività di destinazione non ha accesso all'oggetto passato perché questo oggetto è stato consumato dal bus da una chiamata precedente.
JuliuszJ,

1
Parcelable è il più veloce e con questo generatore ( parcelabler.com ), puoi incollare la tua classe e generare il codice per te. Semplice.
ByWaleed,

1
@ByWaleed ... Sono assolutamente d'accordo, uso sempre questo sito, faccio cose senza problemi. Tuttavia, ho avuto molti tentativi falliti, quando provo ad usare un POJO composto da un altro oggetto. Per qualche ragione il suo risultato non funziona davvero.
Yo Apps,

42

Ho trovato un metodo semplice ed elegante:

  • NO parcelable
  • NO serializzabile
  • NESSUN campo statico
  • Nessun bus eventi

Metodo 1

Codice per la prima attività:

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

Codice per la seconda attività:

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

troverai objSente objReceivedavrai lo stesso hashCode, quindi sono identici.

Ma perché possiamo passare un oggetto Java in questo modo?

In realtà, Android Binder creerà un riferimento JNI globale per l'oggetto java e rilascerà questo riferimento JNI globale quando non ci sono riferimenti per questo oggetto java. binder salverà questo riferimento JNI globale nell'oggetto Binder.

* ATTENZIONE: questo metodo funziona SOLO a meno che le due attività non vengano eseguite nello stesso processo, altrimenti genera ClassCastException su (ObjectWrapperForBinder) getIntent (). GetExtras (). GetBinder ("object_value") *

definizione di ObjectWrapperForBinder di classe

public class ObjectWrapperForBinder extends Binder {

    private final Object mData;

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

    public Object getData() {
        return mData;
    }
}

Metodo 2

  • per il mittente,
    1. utilizzare il metodo nativo personalizzato per aggiungere l'oggetto java alla tabella di riferimento globale JNI (tramite JNIEnv :: NewGlobalRef)
    2. metti il ​​numero intero di ritorno (in realtà, JNIEnv :: NewGlobalRef return jobject, che è un puntatore, possiamo lanciarlo in int in modo sicuro) al tuo Intento (tramite Intent :: putExtra)
  • per il ricevitore
    1. ottenere numeri interi da Intent (tramite Intent :: getInt)
    2. utilizzare il metodo nativo personalizzato per ripristinare l'oggetto java dalla tabella di riferimento globale JNI (tramite JNIEnv :: NewLocalRef)
    3. rimuove l'elemento dalla tabella di riferimento globale JNI (tramite JNIEnv :: DeleteGlobalRef),

Ma il Metodo 2 ha un piccolo ma grave problema, se il ricevitore non riesce a ripristinare l'oggetto java (ad esempio, si verifica un'eccezione prima di ripristinare l'oggetto java o l'attività del ricevitore non esiste affatto), allora l'oggetto java diventerà un orfano o perdita di memoria, il Metodo 1 non ha questo problema, perché Android Binder gestirà questa eccezione

Metodo 3

Per richiamare l'oggetto java in remoto, creeremo un contratto / interfaccia di dati per descrivere l'oggetto java, useremo il file aidl

IDataContract.aidl

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

Codice per la prima attività

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

Codice per la seconda attività:

cambia l'attributo android: process in AndroidManifest.xml in un nome di processo non vuoto per assicurarti che la seconda attività venga eseguita in un altro processo

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

In questo modo, possiamo passare un'interfaccia tra due attività anche se vengono eseguite in processi diversi e chiamare il metodo di interfaccia in remoto

Metodo 4

il metodo 3 non sembra abbastanza semplice perché dobbiamo implementare un'interfaccia di aiuto. Se vuoi semplicemente fare un semplice compito e il valore di ritorno del metodo non è necessario, possiamo usare android.os.Messenger

Codice per la prima attività (mittente):

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

Codice per la seconda attività (destinatario):

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

    }
}

Tutto il Messenger.send verrà eseguito in un gestore in modo asincrono e sequenziale.

In realtà, android.os.Messenger è anche un'interfaccia helpl, se hai il codice sorgente Android, puoi trovare un file chiamato IMessenger.aidl

package android.os;

import android.os.Message;

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

Mi dispiace non aver visto che hai avuto un legame nella tua risposta e penso che anche la tua risposta sia molto elegante.
SkidRunner,

Wow .... Il primo metodo di quest'uomo è eccezionale ..... Quando hai oggetti di dimensioni molto grandi / più grandi che funzionano bene
Karan,

Ho un metodo utente, quindi mi risparmia tempo. Grazie;
ShweLiam,

Grazie mille per il metodo ObjectWrapperForBinder, aiuta davvero!
Vladimir Tolstikov,

40

Puoi anche scrivere i dati dell'oggetto in stringhe e ints temporanei e passarli all'attività. Naturalmente in questo modo, si ottengono i dati trasportati, ma non l'oggetto stesso.

Ma se vuoi solo visualizzarli e non usare l'oggetto in un altro metodo o qualcosa del genere, dovrebbe essere sufficiente. Ho fatto lo stesso modo per visualizzare solo i dati di un oggetto in un'altra attività.

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

Potresti anche passarli direttamente al posto degli avari temporanei, ma in questo modo è più chiaro, secondo me. Inoltre, è possibile impostare gli ivar temporanei su null in modo che vengano presto puliti da GarbageCollector.

In bocca al lupo!

Nota a margine: sovrascrivi toString () invece di scrivere il tuo metodo di stampa.

Come menzionato nei commenti seguenti, ecco come recuperare i dati in un'altra attività:

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

9
recupera nuovamente i tuoi dati con: String fName = getIntent (). getExtras (). getInt ("fname");
Alister,

2
Per recuperare i dati: Bundle extras = getIntent().getExtras(); String val = extras.getString("fname");
Eric Leschinski il

1
Ciò può diventare rapidamente impossibile per i grandi POJO. Piuttosto usa un bus. Vedi il mio post qui sotto.
Steven Mark Ford,

come ho detto nella mia risposta, questo è per semplici casi d'uso in cui non è necessario l'oggetto stesso, ma solo alcuni valori di esso. Non si tratta di essere una supposizione per casi complessi.
MJB,

1
Buona idea per passare un singolo oggetto, ma sto cercando di passare una matrice di dimensioni sconosciute del mio oggetto. Forse la tua soluzione non è per il passaggio di matrici di oggetti.
Muhammad Saqib,

25

Ho creato una classe di aiuto singleton che contiene oggetti temporanei.

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

Invece di mettere i tuoi oggetti all'interno di Intent, usa IntentHelper:

IntentHelper.addObjectForKey(obj, "key");

All'interno della tua nuova attività, puoi ottenere l'oggetto:

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

Tenere presente che una volta caricato, l'oggetto viene rimosso per evitare riferimenti non necessari.


1
Buona idea! Inoltre potrebbe essere possibile creare una classe aggiuntiva ObjectContainer {Object, obj; permanente booleano; ....} L'idea è che, è possibile passare un valore booleano nel metodo add se è necessario mantenere l'oggetto persistente e non rimuoverlo quando si chiama get. Aiuterà a mantenere alcuni oggetti globali. Potrebbe essere una connessione bluetooth aperta ecc.
Umair,

1
Carino ma non reinventare la ruota. Il modello di autobus è elegante e più potente. Vedi il mio post qui sotto.
Steven Mark Ford,

@StevenMarkFord, quindi il modello Bus è ancora valido fino ad oggi? Sto cercando di migliorare una base di codice con un codice come questo accedendo ai dati tra le attività: BookActivity.getInstance().recommendationResponseinRoomsActivity
Woppi

Quando l'attività di ricezione viene ricreata (ad es. Sulla rotazione dello schermo) objdiventa null. Per evitare ciò, objdovrebbe essere conservato da qualche parte per ottenerlo di nuovo. In effetti la soluzione Json memorizza i dati degli oggetti in Intent.
Salvador,

25

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 Utilità comune. Dipende da te.

E. Trasmissione dei dati tramite Intents and Parcelable Interface.

Dipende dalle esigenze del tuo progetto.

A. Database

SQLite è un database open source incorporato in Android. SQLite supporta funzionalità standard di database relazionali come sintassi SQL, transazioni e istruzioni preparate.

Esercitazioni

B. Preferenze condivise

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

Come conservare

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

Usando putString (), putBoolean (), putInt (), putFloat () e putLong () è possibile salvare il dtatype 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 serlizzazione di oggetti viene utilizzata se vogliamo salvare uno stato di oggetto per inviarlo su una rete o è possibile utilizzarlo anche per i propri scopi.

Usa i bean Java e memorizzali 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. Dato 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 la serializzazione degli oggetti 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. Cioè, 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 tutorial per questo fai riferimento a:

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 tramite intenti

Si prega di fare riferimento al tutorial Android - Dati pacchi da passare tra le attività utilizzando le classi pacchi per questa opzione di trasferimento dei dati.


22

Crea la tua classe Customercome segue:

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

}

Nel tuo onCreate()metodo

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

In xyz activityclasse devi usare il seguente codice:

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

..Controlla il codice che stai passando "bundle" come chiave per put cust obj e ottenere da "class" .. per favore usa una chiave "class" o "bundle" ..
AK Joshi

Errore Face: Parcelable rilevato IOException durante la scrittura di oggetti serializzabili
Arul Mani

15

Il modo migliore è di avere una classe (chiamala Control) nella tua applicazione che conterrà una variabile statica di tipo "Cliente" (nel tuo caso). Inizializza la variabile nella tua attività A.

Per esempio:

Control.Customer = CustomerClass;

Quindi vai all'attività B e recuperala dalla classe Control. Non dimenticare di assegnare un null dopo aver utilizzato la variabile, altrimenti la memoria verrà sprecata.


4
@aez Perché è sciatto dal punto di vista del design e si romperà orribilmente se l'intento è mai in un altro processo.

7
Incontrerai problemi quando ripristini la tua app sull'attività B. Poiché l'attività può essere interrotta da Android e l'oggetto non verrà salvato.
Ryan R,

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

Ora vuoi passare l'oggetto di questa classe in startActivity. Basta usare questo:

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

Questo funziona qui perché implementa MyClass Serializable.


puoi per favore spiegare o elaborare altro
Amitsharma,

HomeworkData homeworkData = homeWorksList.get (posizione); Intent intent = new Intent (c, HomeWorkActivitydetail.class); Bundle b = new Bundle (); b.putSerializable ("CompleteData", homeworkData); intent.putExtras (b); c.startActivity (intento); in un momento di aggiunta dell'oggetto mi dà qualche errore per l'aggiunta di elementi oggetto, non possiamo passare l'oggetto completo con questo
Amitsharma,

all'interno dei compiti a casa
Data

12

Se scegli di usare il modo descritto da Samuh, ricorda che possono essere inviati solo valori primitivi. Cioè, valori che sono parcable. Quindi, se il tuo oggetto contiene oggetti complessi, questi non seguiranno. Ad esempio, variabili come Bitmap, HashMap ecc ... Queste sono difficili da superare dall'intento.

In generale si dovrebbe consigliare di inviare tipi di dati primitivi solo come comparse, come String, int, boolean ecc Nel tuo caso sarebbe: String fname, String lname, int age, e String address.

La mia opinione: gli oggetti più complessi vengono condivisi meglio implementando ContentProvider , SDCard , ecc. È anche possibile utilizzare una variabile statica , ma ciò può portare rapidamente a un codice soggetto a errori ...

Ma di nuovo, è solo la mia opinione soggettiva.


8

Sto usando il pacco per inviare dati da un'attività a un'altra attività. Ecco il mio codice che funziona bene nel mio progetto.

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

In attività, usalo in questo modo:

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

In ActivityB usalo in questo modo per ottenere dati:

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

7

Puoi provare a usare quella classe. Il limite è che non può essere utilizzato al di fuori di un processo.

Un'attività:

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

Altre attività:

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

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

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

Recuperare dati su un'altra attività (YourActivity)

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

Questo va bene per un semplice tipo di tipo di dati. Ma se vuoi passare dati complessi tra un'attività. Devi prima serializzare.

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

TypeToken <> è obsoleto. Qual è l'alternativa?
Ragavendra M,

6

Questa domanda è anche discussa in un'altra domanda Stack Overflow. Dai un'occhiata a una soluzione per il passaggio di dati attraverso l'intento utilizzando Serializable . Il punto principale riguarda l'uso Bundledell'oggetto che memorizza i dati necessari all'interno Intent.

 Bundle bundle = new Bundle();

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

 intent.putExtras(bundle);

Per estrarre valori:

 Bundle bundle = new Bundle();

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

Il vantaggio Serializableè la sua semplicità. Tuttavia, dovresti prendere in considerazione l'utilizzo del Parcelablemetodo se hai bisogno di trasferire molti dati, perché Parcelableè specificamente progettato per Android ed è più efficiente di Serializable. Puoi creare un corso Parcelableusando:

  1. uno strumento online - parcelabler
  2. un plug-in per Android Studio - Generatore di codice parcelable Android

5

Creta una classe come la classe bean e implementare l' Serializableinterfaccia. Quindi possiamo passarlo attraverso il intentmetodo, ad esempio:

intent.putExtra("class", BeanClass);

Quindi ottenerlo dall'altra attività, ad esempio:

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

5

Crea due metodi nella tua classe personalizzata in questo modo

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

Ora nel tuo mittente, fai così

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

E nel ricevitore Attività

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

3

Sì, l'uso di un oggetto statico è di gran lunga il modo più semplice per farlo con oggetti personalizzati non serializzabili.


Sì, penso di essere davvero d'accordo con te. Realizzare questi oggetti staticè la soluzione migliore se è semplicemente poco pratico continuare a invocare putExtra()per ogni proprietà che si desidera trasmettere. Ad esempio, in questo momento, voglio passare un oggetto ArrayListche contiene oggetti. Potrei anche fare la mia ArrayList staticinvece.
Matthew Quiros,

3

Gli oggetti Attività Android possono essere distrutti e ricostituiti. Quindi, dovrai usare un altro approccio per guardarli - o qualsiasi oggetto che creino !!! - su. Cioè, potresti passare come riferimento di classe statica ma poi l'handle di oggetti (Java chiama questi "riferimenti", come fa SmallTalk; ma non sono riferimenti nel senso di C o assembly) sarà probabilmente non valido in seguito perché una "caratteristica" di Android OE è che qualsiasi attività può essere annullata e ricostituita in un secondo momento.

La domanda originale chiedeva "Come passare l'oggetto da un'attività all'altra in Android" e nessuno ha risposto. Di sicuro, è possibile serializzare (serializzabile, parcelabile, da / verso JSON) e passare una copia dei dati dell'oggetto e si potrebbe creare un nuovo oggetto con gli stessi dati; ma NON avrà gli stessi riferimenti / handle. Inoltre, molti altri hanno menzionato che è possibile memorizzare il riferimento in un archivio statico. E funzionerà a meno che Android non decida di distruggere la tua attività.

Quindi, per risolvere davvero la domanda originale avresti bisogno di una ricerca statica e ogni oggetto aggiornerà il suo riferimento quando / se viene ricreato. Ad esempio, ogni attività Android si rimetterebbe in riga se si chiamasse onCreate. Puoi anche vedere come alcune persone usano l'elenco delle attività per cercare un'attività per nome. (il sistema sta distruggendo temporaneamente questa istanza dell'attività per risparmiare spazio..getRunningTasks, l'elenco delle attività è effettivamente un elenco specializzato dell'istanza oggetto più recente di ogni attività).

Per riferimento:

Arrestato: "L'attività è completamente oscurata da un'altra attività (l'attività è ora in" background "). Anche un'attività interrotta è ancora viva (l' oggetto Activity viene conservato in memoria , mantiene tutte le informazioni sullo stato e sui membri, ma non lo è collegato al gestore di finestre). Tuttavia, non è più visibile all'utente e può essere ucciso dal sistema quando è necessaria memoria altrove. "

onDestroy "il sistema sta distruggendo temporaneamente questa istanza dell'attività per risparmiare spazio."

Quindi, il bus dei messaggi è una soluzione praticabile. Fondamentalmente "giochi di parole". Invece di provare ad avere riferimenti ad oggetti; quindi riprogettate il progetto per utilizzare MessagePassing anziché SequentialCode. Esponenzialmente più difficile da eseguire il debug; ma ti consente di ignorare questo tipo di comprensione di OperatingEnvironment. In effetti, ogni metodo di accesso all'oggetto è invertito, quindi il chiamante pubblica un messaggio e l'oggetto stesso definisce un gestore per quel messaggio. Molto più codice ma può renderlo robusto con le restrizioni Android OE.

Se tutto ciò che vuoi è l'attività principale (cosa tipica nelle app Android a causa della necessità di "Contesto" ovunque), puoi semplicemente avere ogni Elenco attività come "superiore" nello spazio globale statico ogni volta che viene chiamato onResume. Quindi il tuo AlertDialog o qualunque cosa necessiti di un contesto può semplicemente prenderlo da lì. Inoltre, è un po 'schifoso usare un globale, ma può semplificare il passaggio di un contesto su e giù dappertutto e, sicuramente, quando si utilizza un MessageBus, l'IT è comunque globale.


Otto ha il vantaggio di poterlo eseguire esternamente in una semplice vecchia app Java. Quindi, buono per sviluppatori e test senza dover fare confusione con Android. Otto ha una grande curva di apprendimento e la maggior parte di ciò che risolve è già risolto in modi Android (trasmissione locale ecc.) O in normali approcci di sviluppo di app (puoi scrivere una ricerca globale molto più semplice rispetto alla ricerca globale di Otto, gli approcci normali sono molto più accessibile per vectoring / F3 tramite codice e per passare attraverso il debug).
TimJowers2,

2
  1. So che l'elettricità statica è male, ma sembra che siamo costretti a usarlo qui. Il problema con parceables / seriazables è che le due attività hanno istanze duplicate dello stesso oggetto = spreco di memoria e CPU.

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

Attività di chiamata

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

Attività chiamata (notare che onCreate () e onResume () possono essere chiamati più volte quando il sistema distrugge e ricrea attività)

if (IntentMailBox.content.size()>0)
    level = (Level) IntentMailBox.content.poll();
else
    // Here you reload what you have saved in onPause()
  1. Un altro modo è dichiarare un campo statico della classe che si desidera passare proprio in quella classe. Servirà solo per questo scopo. Non dimenticare che può essere nullo in onCreate, perché il pacchetto dell'app è stato scaricato dalla memoria dal sistema e ricaricato in seguito.

  2. Tenendo presente che è ancora necessario gestire il ciclo di vita delle attività, è possibile che si desideri scrivere tutti i dati direttamente nelle preferenze condivise, doloroso con strutture dati complesse così come sono.


1

Le risposte di cui sopra sono quasi tutte corrette, ma per coloro che non capiscono quelle risposte Android ha un intento di classe potente con l'aiuto di esso condividi i dati tra non solo attività ma altri componenti di Android (ricevitore broadcasr, servizi per contenuti a condizione che utilizziamo la classe ContetnResolver no Intent ). Nella tua attività costruisci intenti

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

Nella tua attività di recupero hai

public class SomeActivity extends AppCompactActivity {

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

}

Devi implementare l'interfaccia Parceable o Serializable sul tuo oggetto per condividere tra le attività. È difficile implementare Parcealbe piuttosto che l' interfaccia serializzabile sull'oggetto, ecco perché Android ha plugin appositamente per questo. Scaricalo e usalo


0

Mi ero sempre chiesto perché non può essere così semplice come chiamare un metodo dell'altra attività. Di recente ho scritto una libreria di utilità che la rende quasi semplice. Puoi verificarlo qui ( https://github.com/noxiouswinter/gnlib_android/wiki/gnlauncher ).

GNLauncher rende l'invio di oggetti / dati a un'attività da un'altra attività ecc. Semplice come chiamare una funzione nell'attività con i dati richiesti come parametri. Introduce la sicurezza del tipo e rimuove tutti gli ostacoli di dover serializzare, collegandosi all'intento usando le chiavi di stringa e annullando lo stesso dall'altra parte.

uso

Definire un'interfaccia con i metodi che si desidera chiamare sull'attività da avviare.

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

Implementare l'interfaccia sopra sopra sull'attività da avviare. Avvisare GNLauncher anche quando l'attività è pronta.

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

Nell'altra attività, ottenere un proxy per l'attività sopra e chiamare qualsiasi metodo con i parametri desiderati.

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

Verrà avviata la prima attività e il metodo verrà richiamato con i parametri richiesti.

Prerequisiti

Consultare https://github.com/noxiouswinter/gnlib_android/wiki#prerequisites per informazioni su come aggiungere le dipendenze.


0

Passa l'oggetto da un'attività a un'altra.

(1) attività di fonte

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

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

(2) attività di destinazione

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

0

Prima usavo impostare l'oggetto con Pacelable o Serializable per il trasferimento, ma ogni volta che aggiungo altre variabili all'oggetto (modello), devo registrarlo tutto. È così comodo.

È facilissimo trasferire oggetti tra attività o frammenti.

DataCache Android


0

Possiamo passare l'oggetto da un'attività a un'altra:

SupplierDetails poSuppliersDetails = new SupplierDetails();

All'interno poSuppliersDetailsabbiamo alcuni valori. Ora sto inviando questo oggetto all'attività di destinazione:

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

Come ottenerlo in ACtivity Due:

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

0

Passa un'attività a un'altra:

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

Ottieni valori:

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

-1

Ciao a tutti vedo molte buone opzioni ma mi chiedevo perché Binding non è stato usato?

Passare un riferimento a un oggetto mi sembra più efficiente della serializzazione e della sterilizzazione degli oggetti, ma non ho fatto un tuffo profondo per vedere se questo è ciò che sta accadendo dietro le quinte.

Creare un Raccoglitore è abbastanza semplice ...

public class MyBinder extends Binder {

    private Object myObject;

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

    public Object getObject() {
        return myObject;
    }

}

E creare il pacco per usarlo non è quel cattivo etere.

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

    };
}

Questa logica è davvero interessante perché in realtà stai passando un riferimento da un'attività all'altra.

Consiglierei di verificare la presenza di valori null e se l'istanza di Binder è MyBinder!

e per implementarlo basta ...

Invialo

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

intent.putExtra("MyParcelable", myParcelable);

Riaverlo

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

Diamine, qualcuno potrebbe impazzire e rendere questo succhiatore un vero generico.

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.