Comment passer un objet d'une activité à une autre sur Android


780

J'essaie de travailler sur l'envoi d'un objet de ma classe de clients à partir de l'un Activityet de l'afficher dans un autre Activity.

Le code de la classe client:

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

Je veux envoyer son objet de l'un Activityà l'autre puis afficher les données sur l'autre Activity.

Comment puis-je y parvenir?


1
vous devriez probablement changer la réponse acceptée en vue de l'opinion de masse.
Rohit Vipin Mathews

J'avais l'habitude de définir l'objet sur Pacelable ou Serializable, mais chaque fois que j'ajoute d'autres variables, je dois tout ajouter aux fonctions pour obtenir et définir Pacelable ou Serializable. j'ai donc fait DataCache pour transférer entre les activités et les fragments. github.com/kimkevin/AndroidDataCache Il est super facile de transférer un objet.
kimkevin

Réponses:


887

Une option pourrait être de laisser votre classe personnalisée implémenter l' Serializableinterface, puis vous pouvez passer des instances d'objet dans l'intention supplémentaire en utilisant la putExtra(Serializable..)variante de la Intent#putExtra()méthode.

Pseudocode :

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

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

Remarque: assurez-vous que chaque classe imbriquée de votre classe personnalisée principale a implémenté une interface sérialisable pour éviter toute exception de sérialisation. Par exemple:

class MainClass implements Serializable {

    public MainClass() {}

    public static class ChildClass implements Serializable {

        public ChildClass() {}
    }
}

126
@OD: Pour ma défense, je n'ai jamais dit que c'était la meilleure option; OP vient de demander des alternatives et j'en ai suggéré une. Merci quand même.
Samuh

83
Pourquoi la sérialisation n'est-elle pas une bonne option? C'est une interface bien connue, il y a de fortes chances que les classes populaires puissent déjà l'implémenter (ArrayList, par exemple, est déjà sérialisable). Pourquoi devriez-vous changer vos objets de données pour ajouter du code supplémentaire simplement pour les passer d'une classe à une autre? Cela semble être une mauvaise conception. Je peux imaginer qu'il puisse y avoir un impact sur les performances à un certain niveau, mais je pense que dans 99% des cas, les gens transmettent de petites quantités de données, et ils s'en moquent. Plus simple et portable, c'est parfois mieux aussi.
Nate

16
@Sander: cette réponse ( stackoverflow.com/questions/2139134/… ) est-elle alors incorrecte? Il dit que Parcelable EST spécifiquement conçu à cet effet (et beaucoup plus rapidement que Serializable). Je suis confus.
Slauma

41
Parcelablepeut être bon pour la vitesse, mais il est compliqué à mettre en œuvre. Et si vous avez 8 objets à passer entre les activités, allez-vous en fabriquer chacun Parcelable? Il serait plus judicieux d'utiliser à la Serializableplace. Lorsque vous implémentez, Parcelablevous devez ajouter beaucoup de code à la classe et classer les champs de manière très spécifique; Serializablenon. En fin de compte, je pense que cela dépend du nombre d'objets que vous passez et de ce que vous essayez de faire.
BlackHatSamurai

15
Serializableest une interface Java standard. Vous marquez simplement une classe Serializable en implantant l'interface, et Java la sérialisera automatiquement dans certaines situations. Parcelableest une interface spécifique à Android où vous implémentez vous-même la sérialisation. Il a été créé pour être beaucoup plus efficace que Serializable et pour contourner certains problèmes avec le schéma de sérialisation Java par défaut
Gaurav Arora

312

Implémentez votre classe avec Serializable. Supposons que c'est votre classe d'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;
}

Nous envoyons l'objet appelé denede l'activité X à l'activité Y. Quelque part dans l'activité X;

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

Dans l'activité Y, nous obtenons l'objet.

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

C'est ça.


1
C'était vraiment utile pour moi. Merci ... Mais lors de la réception de l'objet transmis, la syntaxe devrait être [Deneme dene = (Deneme) i.getSerializableExtra ("sampleObject"); ] ... Est-ce ???
JibW

1
@ MustafaGüven Mais j'obtiens classCastException: java.lang.Longen le faisant. Pouvez-vous expliquer pourquoi?
Shajeel Afzal

Il n'y a aucun rapport avec ma réponse. C'est quelque chose de très différent que vous obtenez. Pourriez-vous partager vos codes?
Mustafa Güven

1
La sérialisation est trop lente pour les gros POJO. L'utilisation d'un bus est un modèle bien meilleur.
Steven Mark Ford

1
Pourquoi devrais-je avoir à préfixer (Serializable)l'objet?
Alston

123
  • L'utilisation de variables statiques globales n'est pas une bonne pratique d' ingénierie logicielle .
  • Conversion des champs d'un objet en primitif types de données peut être une tâche ardue .
  • L'utilisation de sérialisable est OK, mais elle n'est pas efficace en termes de performances sur la plate-forme Android.
  • Parcelable est spécialement conçu pour Android et vous devez l'utiliser. Voici un exemple simple: Passer des objets personnalisés entre les activités Android

Vous pouvez générer du code Parcelable pour votre classe en utilisant ce site .


4
Que faire si mon objet contient un Arraylist imbriqué?
Dr aNdRO

10
Bon peut-être mais il faut vraiment prendre la `` performance '' avec un grain de sel imo. Si cela se fait au prix de la mise en œuvre, Parcelableje préfère garder mes classes POJO agnostiques et utiliser Android Serializable.
VH-NZZ

Je n'accepte pas que vous utilisiez Parcelable. Un modèle BUS simple est beaucoup plus efficace au moment de l'exécution et économise beaucoup de temps de développement.
Steven Mark Ford

15
Selon cette référence, bitbucket.org/afrishman/androidserializationtest Serializable est beaucoup plus rapide que Parcelable. Veuillez cesser de partager ce non-sens de 5 ans sur Parcelable.
afrish

7
En quoi les variables statiques globales "ne sont pas de bonnes pratiques en génie logiciel" Vous pouvez créer quelque chose comme un cache singleton et / ou une grille de données, puis faire circuler les ID ou similaires. Lorsque vous passez des références en Java, vous utilisez de toute façon des variables statiques globales car elles pointent vers le même objet.
breakline

112

Utilisez gson pour convertir votre objet en JSON et lui transmettre l'intention. Dans la nouvelle activité, convertissez le JSON en objet.

Dans votre build.gradle, ajoutez ceci à vos dépendances

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

Dans votre activité, convertissez l'objet en chaîne json:

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

Dans votre activité de réception, reconvertissez la chaîne json en objet d'origine:

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

Pour Kotlin c'est la même chose

Transmettez les données

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

Recevoir les données

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

3
C'est une exagération, gson est juste un type de sérialisation de chaîne en json, il vaut mieux implémenter Serializable ou Paracable.
James Roeiter du

14
Il n'est pas nécessaire d'implémenter sérialisable dans chaque objet et dans chaque projet (perte de temps) si vous pouvez utiliser une bibliothèque (gson) qui gère cela. Et à propos de l'excès, il y a des téléphones dual et quadcore là-bas, ils peuvent même gérer une liste suivant cette idée de réponse.
sagits

4
Je recommanderais également d'utiliser gson car gson peut également sérialiser des listes d'arrays en plus de ce qui précède.
nurgasemetey

4
C'est bien! Dans mon cas, j'utilise une bibliothèque que les objets n'implémentent pas sérialisable ou parcelable. C'est donc ma seule option afaik
Chad Bingham

2
C'est la meilleure solution. Certaines classes sont si simples, vous n'avez pas besoin de trop compliquer leur mise en œuvre en implémentant sérialisable
Ojonugwa Jude Ochalifu

98

En appelant une activité

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

Dans toClass.java recevoir l'activité par

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

Veuillez vous assurer que la classe client implémente le colis

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, j'ai une question. Lorsque vous créez la première classe Intent, vous transmettez fromClass.this comme premier argument. Existe-t-il un moyen de récupérer cet objet dans la classe d'activité de réception?
newman

1
Miliu, fromClass fr = (fromClass) getParent (); c'est ce dont tu avais besoin?
Annonces

Adhava, je l'ai fait, mais fr est nul. Une idée pourquoi?
newman

miliu, veuillez partager votre trace d'exception afin que nous puissions l'examiner.
Annonces

Parcelable a beaucoup de code de plaque de chaudière inutile et est franchement une perte de temps. Utilisez plutôt un bus. Voir mon post ci-dessous.
Steven Mark Ford du

89

D'après mon expérience, il existe trois solutions principales, chacune avec ses inconvénients et ses avantages:

  1. Implémentation de Parcelable

  2. Implémentation de sérialisable

  3. Utilisation d'une bibliothèque de bus d'événements légère (par exemple, EventBus de Greenrobot ou Otto de Square)

Parcelable - rapide et standard Android, mais il a beaucoup de code passe-partout et nécessite des chaînes codées en dur pour référence lors de l'extraction des valeurs (non fortement tapé).

Sérialisable - près de zéro passe-partout, mais c'est l'approche la plus lente et nécessite également des chaînes codées en dur lors de l'extraction des valeurs (non fortement typées).

Bus d'événements - zéro passe-partout, approche la plus rapide et ne nécessite pas de chaînes codées en dur, mais il nécessite une dépendance supplémentaire (bien que généralement léger, ~ 40 Ko)

J'ai publié une comparaison très détaillée autour de ces trois approches, y compris des repères d'efficacité.


4
Le lien vers l'article est mort. Toujours disponible sur webarchive: web.archive.org/web/20160917213123/http://…
OlivierH


Le problème d'utilisation du bus d'événements est lorsque l'activité cible est recréée en raison de la rotation par exemple. Dans ce cas, l'activité cible n'a pas accès à l'objet transmis car cet objet a été consommé depuis le bus par un appel antérieur.
JuliuszJ

1
Parcelable est le plus rapide et avec ce générateur ( parcelabler.com ), vous pouvez coller votre classe et il peut générer le code pour vous. Facile.
ByWaleed

1
@ByWaleed ... Je suis absolument d'accord, j'utilise toujours ce site, fait des trucs sans tracas. Cependant, j'ai eu beaucoup d'essais infructueux, lorsque j'essaie d'utiliser un POJO qui est composé d'un autre objet. Pour une raison quelconque, sa sortie ne fonctionne pas vraiment.
Yo Apps

42

J'ai trouvé une méthode simple et élégante:

  • PAS de colis
  • PAS sérialisable
  • AUCUN champ statique
  • Aucun bus d'événement

Méthode 1

Code pour la première activité:

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

Code pour la deuxième activité:

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

vous trouverez objSentet objReceivedaurez les mêmes hashCode, ils sont donc identiques.

Mais pourquoi peut-on passer un objet java de cette façon?

En fait, Android Binder créera une référence JNI globale pour l'objet Java et libérera cette référence JNI globale lorsqu'il n'y a pas de référence pour cet objet Java. binder enregistrera cette référence JNI globale dans l'objet Binder.

* ATTENTION: cette méthode fonctionne UNIQUEMENT sauf si les deux activités s'exécutent dans le même processus, sinon lancez ClassCastException à (ObjectWrapperForBinder) getIntent (). GetExtras (). GetBinder ("object_value") *

classe ObjectWrapperForBinder, définition

public class ObjectWrapperForBinder extends Binder {

    private final Object mData;

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

    public Object getData() {
        return mData;
    }
}

Méthode 2

  • pour l'expéditeur,
    1. utiliser une méthode native personnalisée pour ajouter votre objet java à la table de référence globale JNI (via JNIEnv :: NewGlobalRef)
    2. mettez l'entier de retour (en fait, JNIEnv :: NewGlobalRef return jobject, qui est un pointeur, nous pouvons le convertir en int en toute sécurité) dans votre intention (via Intent :: putExtra)
  • pour le récepteur
    1. récupère l'entier de Intent (via Intent :: getInt)
    2. utiliser une méthode native personnalisée pour restaurer votre objet java à partir de la table de référence globale JNI (via JNIEnv :: NewLocalRef)
    3. supprimer l'élément de la table de référence globale JNI (via JNIEnv :: DeleteGlobalRef),

Mais la méthode 2 a un petit mais grave problème, si le récepteur ne parvient pas à restaurer l'objet java (par exemple, une exception se produit avant de restaurer l'objet java, ou l'activité du récepteur n'existe pas du tout), alors l'objet java deviendra un orphelin ou fuite de mémoire, la méthode 1 n'a pas ce problème, car Android Binder gérera cette exception

Méthode 3

Pour invoquer l'objet java à distance, nous allons créer un contrat / interface de données pour décrire l'objet java, nous utiliserons le fichier aidl

IDataContract.aidl

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

Code pour la première activité

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

Code pour la deuxième activité:

changez l'attribut android: process dans AndroidManifest.xml en un nom de processus non vide pour vous assurer que la deuxième activité s'exécute dans un autre processus

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

De cette façon, nous pouvons passer une interface entre deux activités même si elles s'exécutent dans un processus différent, et appeler la méthode d'interface à distance

Méthode 4

la méthode 3 ne semble pas assez simple car nous devons implémenter une interface aidl. Si vous voulez simplement faire une tâche simple et que la valeur de retour de la méthode n'est pas nécessaire, nous pouvons utiliser android.os.Messenger

Code de la première activité (expéditeur):

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

Code de la deuxième activité (récepteur):

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

    }
}

Tous les Messenger.send s'exécuteront dans un gestionnaire de manière asynchrone et séquentielle.

En fait, android.os.Messenger est également une interface aidl, si vous avez le code source android, vous pouvez trouver un fichier nommé IMessenger.aidl

package android.os;

import android.os.Message;

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

Désolé, je n'ai pas vu que vous aviez une liaison dans votre réponse aussi, je pense que votre réponse est également très élégante.
SkidRunner

Wow .... La 1ère méthode de cet homme est formidable ..... Quand vous avez des objets de très grande taille qui fonctionnent bien
karan

J'utilise la méthode un. Donc, vous économisez mon temps. Merci;
ShweLiam

Merci beaucoup pour la méthode ObjectWrapperForBinder, ça aide vraiment!
Vladimir Tolstikov

40

Vous pouvez également écrire les données de l'objet dans des chaînes et des entiers temporaires et les transmettre à l'activité. Bien sûr, de cette façon, vous obtenez les données transportées, mais pas l'objet lui-même.

Mais si vous voulez simplement les afficher et ne pas utiliser l'objet dans une autre méthode ou quelque chose comme ça, cela devrait suffire. Je l'ai fait de la même manière pour afficher simplement les données d'un objet dans une autre activité.

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

Vous pouvez également les passer directement au lieu des ivars temporaires, mais de cette façon, c'est plus clair, à mon avis. En outre, vous pouvez définir les ivars temporaires sur null afin qu'ils soient nettoyés plus tôt par GarbageCollector.

Bonne chance!

Sur une note latérale: remplacez toString () au lieu d'écrire votre propre méthode d'impression.

Comme mentionné dans les commentaires ci-dessous, voici comment récupérer vos données dans une autre activité:

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

9
récupérez à nouveau vos données avec: String fName = getIntent (). getExtras (). getInt ("fname");
Alister

2
Pour récupérer les données: Bundle extras = getIntent().getExtras(); String val = extras.getString("fname");
Eric Leschinski

1
Cela peut rapidement devenir impossible pour les grands POJO. Utilisez plutôt un bus. Voir mon post ci-dessous.
Steven Mark Ford

comme je l'ai mentionné dans ma réponse, il s'agit de cas d'utilisation simples où vous n'avez pas besoin de l'objet lui-même, mais plutôt de quelques valeurs de celui-ci. Ce n'est pas ment d'être une solution pour des cas d'utilisation complexes.
MJB

1
Bonne idée de passer un seul objet, mais j'essaie de passer un tableau de taille inconnue de mon objet. Peut-être que votre solution n'est pas de passer des tableaux d'objets.
Muhammad Saqib

25

J'ai créé une classe d'aide singleton qui contient des objets temporaires.

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

Au lieu de placer vos objets dans Intent, utilisez IntentHelper:

IntentHelper.addObjectForKey(obj, "key");

Dans votre nouvelle activité, vous pouvez obtenir l'objet:

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

Gardez à l'esprit qu'une fois chargé, l'objet est supprimé pour éviter les références inutiles.


1
Bonne idée! En outre, vous pouvez créer une classe supplémentaire ObjectContainer {Object, obj; permanent booléen; ....} L'idée est que, vous pouvez passer une méthode booléenne dans add si vous devez garder un objet persistant et ne pas le supprimer lorsque nous appelons get. Cela aidera à conserver certains objets globaux. Comme peut être une connexion Bluetooth ouverte, etc.
Umair

1
Mignon mais ne réinventez pas la roue. Le modèle de bus est élégant et plus puissant. Voir mon post ci-dessous.
Steven Mark Ford

@StevenMarkFord, le modèle de bus est-il toujours valable jusqu'à ce jour? J'essaie d'améliorer une base de code avec un code comme celui-ci en accédant aux données entre les activités: BookActivity.getInstance().recommendationResponsedansRoomsActivity
Woppi

Lorsque l'activité de réception est recréée (par exemple sur la rotation de l'écran) objdevient null. Pour éviter cela, objdoit être stocké quelque part pour le récupérer. En effet, la solution Json stocke les données d'objets dans Intent.
Salvador

25

Il existe deux façons d'accéder aux variables ou aux objets dans d'autres classes ou activités.

A. Base de données

B. Préférences partagées.

C. Sérialisation d'objets.

D. Une classe pouvant contenir des données communes peut être nommée Common Utilities. Cela dépend de toi.

E. Transmission des données via les intentions et l'interface parcelable.

Cela dépend des besoins de votre projet.

A. Base de données

SQLite est une base de données open source intégrée à Android. SQLite prend en charge les fonctionnalités de base de données relationnelles standard telles que la syntaxe SQL, les transactions et les instructions préparées.

Tutoriels

B. Préférences partagées

Supposons que vous souhaitiez stocker le nom d'utilisateur. Il y aura donc maintenant deux choses, un nom d'utilisateur clé , valeur valeur.

Comment conserver

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

En utilisant putString (), putBoolean (), putInt (), putFloat () et putLong (), vous pouvez enregistrer le dtatype souhaité.

Comment aller chercher

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

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

C. Sérialisation d'objets

La sérialisation d'objets est utilisée si nous voulons enregistrer un état d'objet pour l'envoyer sur un réseau ou si vous pouvez également l'utiliser pour votre usage.

Utilisez des beans Java et stockez-le comme l'un de ses domaines et utilisez des getters et setter pour cela.

JavaBeans sont des classes Java qui ont des propriétés. Considérez les propriétés comme des variables d'instance privées. Puisqu'ils sont privés, la seule façon d'y accéder depuis l'extérieur de leur classe est par le biais de méthodes dans la classe. Les méthodes qui modifient la valeur d'une propriété sont appelées méthodes setter et les méthodes qui récupèrent la valeur d'une propriété sont appelées méthodes getter.

public class VariableStorage implements Serializable  {

    private String inString;

    public String getInString() {
        return inString;
    }

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

Définissez la variable dans votre méthode de messagerie à l'aide de

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

Utilisez ensuite la sérialisation d'objets pour sérialiser cet objet et dans votre autre classe désérialiser cet objet.

Dans la sérialisation, un objet peut être représenté comme une séquence d'octets qui inclut les données de l'objet ainsi que des informations sur le type de l'objet et les types de données stockées dans l'objet.

Une fois qu'un objet sérialisé a été écrit dans un fichier, il peut être lu à partir du fichier et désérialisé. Autrement dit, les informations de type et les octets qui représentent l'objet et ses données peuvent être utilisés pour recréer l'objet en mémoire.

Si vous voulez un tutoriel pour cela, référez-vous à:

D. CommonUtilities

Vous pouvez créer vous-même une classe qui peut contenir des données communes dont vous avez souvent besoin dans votre projet.

Échantillon

public class CommonUtilities {

    public static String className = "CommonUtilities";

}

E. Transmission de données par des intentions

Veuillez consulter le didacticiel Android - Données de parcelle pour passer d'une activité à l'autre à l'aide de classes de parcelle pour cette option de transmission de données.


22

Créez votre propre classe Customercomme suit:

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

}

Dans votre onCreate()méthode

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

En xyz activityclasse, vous devez utiliser le code suivant:

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

..Vérifiez votre code que vous passez "bundle" comme clé pour mettre obj cust & obtenir de "classe" ..pls utiliser une clé soit "classe" ou "bundle" ..
AK Joshi

Je fais face à une erreur: Parcelable a rencontré IOException lors de l'écriture d'un objet sérialisable
Arul Mani

15

La meilleure façon est d'avoir une classe (appelez-la Control) dans votre application qui contiendra une variable statique de type 'Customer' (dans votre cas). Initialisez la variable dans votre activité A.

Par exemple:

Control.Customer = CustomerClass;

Ensuite, allez à l'activité B et récupérez-la dans la classe Control. N'oubliez pas d'attribuer un null après avoir utilisé la variable, sinon la mémoire sera gaspillée.


4
@aez Parce que c'est bâclé du point de vue de la conception et qu'il se brisera horriblement si l'intention est jamais dans un autre processus.

7
Vous rencontrerez des problèmes lors de la reprise de votre application à l'activité B. Étant donné que l'activité peut être supprimée par Android et que l'objet ne sera pas enregistré.
Ryan R

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

Vous voulez maintenant passer l'objet de cette classe dans startActivity. Utilisez simplement ceci:

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

Cela fonctionne ici car MyClass implémente Serializable.


pouvez-vous s'il vous plaît expliquer ou élaborer plus
Amitsharma

HomeworkData homeworkData = homeWorksList.get (position); Intention intention = nouvelle intention (c, HomeWorkActivitydetail.class); Bundle b = nouveau Bundle (); b.putSerializable ("CompleteData", homeworkData); intent.putExtras (b); c.startActivity (intention); à un moment de l'ajout d'objet me donne une erreur pour l'ajout d'éléments d'objet, ne pouvons-nous pas passer un objet complet avec cela
Amitsharma

à l'intérieur des devoirs Données j'ai quelques valeurs celles-ci sont venues s'ajouter
Amitsharma

12

Si vous choisissez d'utiliser la façon dont Samuh décrit, n'oubliez pas que seules les valeurs primitives peuvent être envoyées. Autrement dit, des valeurs parcellables. Donc, si votre objet contient des objets complexes, ceux-ci ne suivront pas. Par exemple, des variables comme Bitmap, HashMap etc ... Ce sont difficiles à passer par l'intention.

En général , je vous conseille d'envoyer seulement primitifs comme figurants types de données, comme String, int, booléen , etc. Dans votre cas , il serait: String fname, String lname, int ageet String address.

Mon avis: les objets plus complexes sont mieux partagés en implémentant un ContentProvider , une SDCard , etc. Il est également possible d'utiliser une variable statique , mais cela peut rapidement conduire à un code sujet aux erreurs ...

Mais encore une fois, c'est juste mon opinion subjective.


8

J'utilise parcelable pour envoyer des données d'une activité à une autre activité. Voici mon code qui fonctionne bien dans mon projet.

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

En activité, utilisez-le comme ceci:

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

Dans ActivityB, utilisez-le comme ceci pour obtenir des données:

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

7

Vous pouvez essayer d'utiliser cette classe. La limitation est qu'elle ne peut pas être utilisée en dehors d'un processus.

Une activité:

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

Autre activité:

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

Démarrez une autre activité à partir de cette activité et passez les paramètres via Bundle Object

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

Retrouver des données sur une autre activité (YourActivity)

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

C'est correct pour un type de type de données simple. Mais si vous voulez transmettre des données complexes entre les activités. Vous devez d'abord le sérialiser.

Ici, nous avons le modèle des employés

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

    getters...
    setters...
}

Vous pouvez utiliser la bibliothèque Gson fournie par Google pour sérialiser les données complexes comme celle-ci

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 <> est obsolète. Quel est l'alternative?
Ragavendra M

6

Cette question est également abordée dans une autre question Stack Overflow. Veuillez jeter un œil à une solution pour transmettre des données via l'intention en utilisant Serializable . Le point principal est d'utiliser un Bundleobjet qui stocke les données nécessaires à l'intérieur Intent.

 Bundle bundle = new Bundle();

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

 intent.putExtras(bundle);

Pour extraire des valeurs:

 Bundle bundle = new Bundle();

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

L'avantage de Serializablesa simplicité. Cependant, vous devriez envisager d'utiliser la Parcelableméthode si vous avez besoin de transférer de nombreuses données, car il Parcelableest spécialement conçu pour Android et il est plus efficace que Serializable. Vous pouvez créer une Parcelableclasse en utilisant:

  1. un outil en ligne - parcelabler
  2. un plugin pour Android Studio - Générateur de code Parcelable Android

5

Créez une classe comme la classe bean et implémentez l' Serializableinterface. Ensuite, nous pouvons le passer par la intentméthode, par exemple:

intent.putExtra("class", BeanClass);

Ensuite, récupérez-le de l'autre activité, par exemple:

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

5

Créez deux méthodes dans votre classe personnalisée comme celle-ci

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

Maintenant, dans votre activité d'expéditeur, faites comme ça

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

Et dans votre activité de récepteur

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

3

Oui, l'utilisation d'un objet statique est de loin la manière la plus simple de le faire avec des objets personnalisés non sérialisables.


Ouais, je pense que je suis d'accord avec toi. La fabrication de ces objets staticest la meilleure solution de contournement s'il est tout simplement impossible de continuer à invoquer putExtra()pour chaque propriété que vous souhaitez transmettre. Par exemple, en ce moment, je veux passer un ArrayListqui contient des objets. Je ferais aussi bien de créer ma liste de tableaux static.
Matthew Quiros

3

Les objets d'activité Android peuvent être détruits et reconstitués. Donc, vous devrez utiliser une autre approche pour les regarder - ou tout objet qu'ils créent !!! - en haut. Autrement dit, vous pouvez passer comme référence de classe statique mais le descripteur d'objet (Java appelle ces "références", comme le fait SmallTalk; mais ce ne sont pas des références au sens de C ou d'assemblage) sera peut-être invalide plus tard car une "fonctionnalité" d'Android OE est n'importe quelle activité peut être annihilée et reconstituée plus tard.

La question initiale demandait "Comment passer un objet d'une activité à une autre dans Android" et personne n'a répondu à cela. Bien sûr, vous pouvez sérialiser (Sérialisable, Parcelable, vers / depuis JSON) et transmettre une copie des données de l'objet et un nouvel objet ayant les mêmes données pourrait être créé; mais il n'aura PAS les mêmes références / poignées. De plus, de nombreux autres ont mentionné que vous pouvez stocker la référence dans un magasin statique. Et cela fonctionnera à moins qu'Android ne décide de détruire votre activité.

Donc, pour vraiment résoudre la question d'origine, vous auriez besoin d'une recherche statique et chaque objet mettra à jour sa référence quand / s'il est recréé. Par exemple, chaque activité Android se réinscrirait si son onCreate était appelé. Vous pouvez également voir comment certaines personnes utilisent la liste des tâches pour rechercher une activité par nom. (le système détruit temporairement cette instance de l'activité pour économiser de l'espace ... getRunningTasks, la liste des tâches est en fait une liste spécialisée de l'instance d'objet la plus récente de chaque activité).

Pour référence:

Arrêté: "L'activité est complètement masquée par une autre activité (l'activité est maintenant en" arrière-plan "). Une activité arrêtée est également toujours en vie (l' objet Activité est conservé en mémoire , il conserve toutes les informations d'état et de membre, mais n'est pas attaché au gestionnaire de fenêtres). Cependant, il n'est plus visible pour l'utilisateur et il peut être détruit par le système lorsque de la mémoire est nécessaire ailleurs. "

onDestroy "le système détruit temporairement cette instance de l'activité pour économiser de l'espace."

Ainsi, le Message Bus est une solution viable. Il s'agit essentiellement de "punts". Plutôt que d'essayer d'avoir des références à des objets; puis vous ré-architecturez votre conception pour utiliser MessagePassing au lieu de SequentialCode. Exponentiellement plus difficile à déboguer; mais cela vous permet d'ignorer ce type de compréhension de OperatingEnvironment. En effet, chaque accès à la méthode objet est inversé de sorte que l'appelant publie un message et que l'objet définit lui-même un gestionnaire pour ce message. Beaucoup plus de code mais peut le rendre robuste avec les restrictions Android OE.

Si tout ce que vous voulez, c'est l'activité supérieure (une chose typique dans les applications Android en raison du fait que le "contexte" est nécessaire partout), alors vous pouvez simplement avoir chaque activité elle-même répertoriée comme "top" dans l'espace global statique chaque fois que son onResume est appelé. Ensuite, votre AlertDialog ou tout ce qui a besoin d'un contexte peut simplement le saisir à partir de là. En outre, il est un peu dégoûtant d'utiliser un global mais peut simplifier la transmission d'un contexte de haut en bas partout et, bien sûr, lorsque vous utilisez un MessageBus, alors IL EST global de toute façon.


Otto a l'avantage de pouvoir l'exécuter en externe dans une simple ancienne application Java. Donc, bon pour le développement et les tests sans avoir à jouer avec Android. Otto a une grande courbe d'apprentissage et la plupart de ce qu'il résout est déjà résolu de manière Android (diffusion locale, etc.) ou dans des approches de développement d'applications normales (vous pouvez écrire une recherche globale beaucoup plus simple que la recherche globale d'Otto, les approches normales sont beaucoup plus plus accessible pour la vectorisation / F3 à travers le code et pour passer par le débogage).
TimJowers2

2
  1. Je sais que l'électricité statique est mauvaise, mais il semble que nous soyons obligés de l'utiliser ici. Le problème avec les parceables / seriazables est que les deux activités ont des instances en double du même objet = perte de mémoire et de CPU.

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

Activité d'appel

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

Activité appelée (notez que onCreate () et onResume () peuvent être appelés plusieurs fois lorsque le système détruit et recrée des activités)

if (IntentMailBox.content.size()>0)
    level = (Level) IntentMailBox.content.poll();
else
    // Here you reload what you have saved in onPause()
  1. Une autre façon consiste à déclarer un champ statique de la classe que vous souhaitez transmettre dans cette même classe. Il ne servira qu'à cette fin. N'oubliez pas qu'il peut être nul dans onCreate, car votre package d'application a été déchargé de la mémoire par le système et rechargé plus tard.

  2. En gardant à l'esprit que vous devez toujours gérer le cycle de vie de l'activité, vous souhaiterez peut-être écrire toutes les données directement dans les préférences partagées, pénibles avec des structures de données complexes telles quelles.


1

Les réponses ci-dessus sont presque toutes correctes, mais pour ceux qui ne comprennent pas ces réponses, Android a une classe d' intention puissante à l'aide de celle-ci, vous partagez des données entre non seulement l'activité mais d'autres composants d'Android (récepteur Broadcasr, services pour le contenu à condition d'utiliser la classe ContetnResolver no Intent ). Dans votre activité, vous construisez une intention

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

Dans votre activité de réception, vous avez

public class SomeActivity extends AppCompactActivity {

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

}

Vous devez implémenter une interface Parceable ou Serializable sur votre objet afin de partager entre les activités. Il est difficile d'implémenter Parcealbe plutôt que l' interface sérialisable sur un objet, c'est pourquoi Android a un plugin spécialement pour cela. Téléchargez-le et utilisez-le


0

Je m'étais toujours demandé pourquoi cela ne pouvait pas être aussi simple que d'appeler une méthode de l'autre activité. J'ai récemment écrit une bibliothèque d'utilitaires qui la rend presque aussi simple que cela. Vous pouvez le vérifier ici ( https://github.com/noxiouswinter/gnlib_android/wiki/gnlauncher ).

GNLauncher rend l'envoi d'objets / données à une activité à partir d'une autre activité, etc. aussi simple que d'appeler une fonction dans cette activité avec les données requises comme paramètres. Il introduit la sécurité des types et supprime tous les obstacles liés à la sérialisation, à l'attachement à l'intention à l'aide de clés de chaîne et à l'annulation à l'autre extrémité.

Usage

Définissez une interface avec les méthodes que vous souhaitez appeler sur l'activité à lancer.

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

Implémentez l'interface ci-dessus sur l'activité à lancer. Informez également GNLauncher lorsque l'activité est prête.

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

Dans l'autre activité, obtenez un proxy pour l'activité ci-dessus et appelez n'importe quelle méthode avec les paramètres souhaités.

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

La première activité sera lancée et la méthode appelée avec les paramètres requis.

Conditions préalables

Veuillez vous référer à https://github.com/noxiouswinter/gnlib_android/wiki#prerequisites pour plus d'informations sur la façon d'ajouter les dépendances.


0

Passer l'objet d'une activité à une autre.

(1) activité source

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

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

(2) activité de destination

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

0

J'avais l'habitude de définir un objet avec Pacelable ou Serializable à transférer, mais chaque fois que j'ajoute d'autres variables à l'objet (modèle), je dois tout enregistrer. C'est tellement gênant.

Il est super facile de transférer un objet entre des activités ou des fragments.

Android DataCache


0

On peut passer l'objet d'une activité à une autre:

SupplierDetails poSuppliersDetails = new SupplierDetails();

A l'intérieur, poSuppliersDetailsnous avons quelques valeurs. Maintenant, j'envoie cet objet à l'activité cible:

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

Comment obtenir cela dans ACtivityTwo:

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

0

Passer une activité à une autre:

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

Obtenez des valeurs:

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

-1

Bonjour à tous, je vois beaucoup de bonnes options, mais je me demandais pourquoi la liaison n'a pas été utilisée?

Passer une référence à un objet me semble tout simplement plus efficace que sérialiser et déstériliser des objets, mais je n'ai pas fait une plongée profonde pour voir si c'est ce qui se passe dans les coulisses.

Créer un classeur est assez simple ...

public class MyBinder extends Binder {

    private Object myObject;

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

    public Object getObject() {
        return myObject;
    }

}

Et créer la parcellaire pour l'utiliser n'est pas si mauvais que l'éther.

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

    };
}

Cette logique est vraiment cool parce que vous passez en fait une référence d'une activité à l'autre.

Je conseillerais de vérifier les valeurs nulles et si l'instance de Binder est MyBinder!

et pour mettre en œuvre cela, vous venez de ...

Envoyez-le

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

intent.putExtra("MyParcelable", myParcelable);

Récupérer

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

Heck quelqu'un pourrait devenir fou et faire de ce meunier un vrai générique.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.