42 votes

Comment passer un objet personnalisé dans un Bundle ?

J'essaie de passer mon propre objet personnalisé dans un bundle :

Bundle b = new Bundle();
                STMessage message = (STMessage)a.getAdapter().getItem(position);
                b.putObject("message",message);

J'obtiens l'erreur suivante :

The method putObject(String, Object) is undefined for the type Bundle

58voto

Ryan Reeves Points 6265

Une solution consiste à faire en sorte que votre objet personnalisé mette en œuvre l'interface Parcelable et à utiliser la fonction Bundle.putParcelable/Bundle.getParcelable

21voto

Sam Points 2090

Classe de modèle

package com.sam.bundleobjectpass;

import java.io.Serializable;

/**
 * Created by Samir on 31.8.2016.
 */
public class Model implements Serializable {
    private String name;
    private String surName;
    private int age;

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

    public String getName() {
        return name;
    }

    public String getSurName() {
        return surName;
    }

    public int getAge() {
        return age;
    }

}

Activité principale

public class MainActivity extends AppCompatActivity {

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

        Model model = new Model("Sam", "Sami",32);

        Intent i = new Intent(MainActivity.this, ReceiverActivity.class);
        i.putExtra("Editing", model); // sending our object. In Kotlin is the same
        startActivity(i);

    }
}

Activité du récepteur

public class ReceiverActivity extends Activity {

    TextView txt_name;
    TextView txt_surname;
    TextView txt_age;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.second);

        txt_name = (TextView)findViewById(R.id.txt_name);
        txt_surname = (TextView)findViewById(R.id.txt_surname);
        txt_age = (TextView)findViewById(R.id.txt_age);
        // receiving our object
        Model model = (Model) getIntent().getSerializableExtra("Editing");

        txt_name.setText(model.getName());
        txt_surname.setText(model.getSurName());
        txt_age.setText(""+model.getAge());

    }
}

// Kotlin

val model: ProgramModel? = intent.getSerializableExtra("Editing") as ProgramModel?
        model?.let { // means if not null or empty
            txt_act_daily_topic.text = it.title
        }

19voto

Emmanuel Mtali Points 1077

Étant donné que l'utilisation de Parsable est conçu pour le transport IPC à haute performance, comme mentionné dans certains commentaires, j'ai essayé d'utiliser une approche différente.

Mon approche utilise GSON bibliothèque de google.

Exemple

public class Person{
    private String name;
    private int age;
    // Getter and Setters omitted
}

Vous pouvez avoir une méthode dans la classe utilitaire qui renvoie l'instance Gson, ceci dans un souci de propreté du code et d'organisation. J'utiliserai GsonBuilder au cas où quelqu'un voudrait enregistrer un adaptateur personnalisé.

public class Utils {
    private static Gson gson;

    public static Gson getGsonParser() {
        if(null == gson) {
            GsonBuilder builder = new GsonBuilder();
            gson = builder.create();
        }
        return gson;
    }
}

L'heure de vérité !

PUT

Bundle args = new Bundle();
String personJsonString = Utils.getGsonParser().toJson(person);
args.putString(PERSON_KEY, personJsonString);

GET

Bundle args = getArguments();
String personJsonString = args.getString(PERSON_KEY);
Person person= Utils.getGsonParser().fromJson(personJsonString, Person.class);

Actuellement, je ne connais pas les limites de performance de cette approche. Mais elle fonctionne très bien

9voto

Squonk Points 28943

Rendez votre objet personnalisé parcelable ou sérialisable, puis utilisez putParcelable ou putSerializable.

En fonction de la complexité de votre objet, l'un ou l'autre peut s'avérer plus facile.

0voto

JAL Points 2276

Comme l'a déclaré Ryan. Par ailleurs, si vous ne souhaitez transmettre qu'un seul objet lors d'un soft kill, envisagez d'utiliser onRetainConfigurationInstance et getLastNonConfigurationInstance pour transmettre l'objet sérialisable. Toute l'arborescence des objets doit être sérialisable. Si vous passez l'objet via une intention, envisagez de refactoriser le code de l'objet en un code Parceable plus tard, une fois que l'architecture s'est stabilisée. Enfin, envisagez d'utiliser le nom pleinement qualifié de la classe lorsque vous stockez l'objet dans le Bundle, comme dans :

inPWState= (PasswordState) getIntent().getSerializableExtra("jalcomputing.confusetext.PasswordState");

J'espère que cela vous aidera. JAL

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X