How to pass custom object in Bundle?

98,181

Solution 1

One way is to have your custom object implement the Parcelable interface and use Bundle.putParcelable/Bundle.getParcelable

Solution 2

Model Class

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


}

MainActivity

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

    }
}

ReceiverActivity

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
        }

Solution 3

Since using Parsable is designed for high performance IPC transport as mentioned in some of the comments, I tried using a different approach.

My approach uses GSON library by google.

Example

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

You can have a method in utility class that returns Gson instance, this is for the sake of clean code and organisation. I will use GsonBuilder incase someone what to register custom adapter.

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

Moment of truth!

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

Currently I don't know the performance limitation of this approach. But it works just fine

Solution 4

Make your custom object Parcelable or Serializable then use putParcelable or putSerializable.

Depending on the complexity of your object one or other may be easier.

Share:
98,181

Related videos on Youtube

Sheehan Alam
Author by

Sheehan Alam

iOS, Android and Mac Developer. i can divide by zero.

Updated on November 16, 2021

Comments

  • Sheehan Alam
    Sheehan Alam over 2 years

    I am trying to pass my own custom object into a bundle:

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

    I get the error:

    The method putObject(String, Object) is undefined for the type Bundle
    
  • dmon
    dmon about 13 years
    The documentation states that you should NOT use Serializable as your go-to parceling mechanism. Because it uses reflection, it's quite heavy on the system. See developer.android.com/reference/android/os/Parcel.html (look for writeSerializable)
  • Ryan Reeves
    Ryan Reeves about 13 years
    I didn't realize that, thank you for the correction. Answer updated.
  • dmon
    dmon about 13 years
    No problem! It is weird that the docs don't mention this caveat in the Bundle one.
  • WindRider
    WindRider over 7 years
    Something very important must be noted. Bundle does NOT do the actual parcelation or serialization. The Parcel class does. Whenever external system decides (for example activity cold recreation, on soft recreation that is simple rotation, parcelation might not take place at all). Bundle just caches the complex objects. One time I assumed the objects are flattened and this wrong assumption led to nasty leaks and 2 days to find them.
  • Deepak Yadav
    Deepak Yadav almost 6 years
    We can also use putSerializable which puts a serialized object into the bundle make your class serializable using Serializable interface
  • Md. Rejaul Karim
    Md. Rejaul Karim over 3 years
    This question is about to pass data using bundle, not Intent.