Parcelable: send objects to another Activity

You can use Intent.putExtra / getExtras to send individual pieces of information to a new activity.

What if you want to send an entire object, or an Array of objects? Answer: use the Parcelable interface.

Parcelable tutorial from CodePath

Example code using a custom Robot class. The example creates Robot objects and sends one to a second Activity (ItemActivity) when its view is touched from a ListView.

Robot class (implementing Parcelable interface)

  • Overrides describeContent()
  • Overrides writeToParcel(Parcel dest, int flags)
  • Adds a new constructor: Robot(Parcel in)
  • Creates public static final Parcelable.Creator<Robot> CREATOR
    • CREATOR overrides createFromParcel() and newArray()

You can use a combination of auto-completing code in Android Studio plus copy/paste and changing the class names to fit your app.

import android.os.Parcel;
import android.os.Parcelable;

public class Robot implements Parcelable {
    String name;
    int motors;
    boolean sentient;

    public Robot(String name, int motors, boolean sentient) {
        this.name = name;
        this.motors = motors;
        this.sentient = sentient;
    }

    public Robot(Parcel in){
        name = in.readString();
        motors = in.readInt();
        sentient = in.readByte() != 0;
    }

    @Override
    public String toString() {
        return "Robot Name: " + name;
    }

    public String getName() {
        return name;
    }

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

    public int getMotors() {
        return motors;
    }

    public void setMotors(int motors) {
        this.motors = motors;
    }

    public boolean isSentient() {
        return sentient;
    }

    public void setSentient(boolean sentient) {
        this.sentient = sentient;
    }

    @Override
    public int describeContents() {
        return 0;
    }
    public static final Parcelable.Creator<Robot> CREATOR = new Parcelable.Creator<Robot>() {

        @Override
        public Robot createFromParcel(Parcel source) {
            return new Robot(source);
        }

        @Override
        public Robot[] newArray(int size) {
            return new Robot[size];
        }
    };
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeInt(motors);
        dest.writeByte((byte) (sentient ? 1 : 0));
    }
}

MainActivity Class

  • This part is very easy with a Parcelable object: just add the object as an extra!
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    ArrayList<Robot> robots;
    ArrayList<String> things;
    ListView lv;

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

        robots = new ArrayList<Robot>();
        robots.add(new Robot("Optimus Prime", 12, true));
        robots.add(new Robot("Wall-E", 8, true));
        robots.add(new Robot("FRC967", 9, false));
        robots.add(new Robot("R2-D2", 15, true));

        lv = findViewById(R.id.listview1);
        ArrayAdapter<Robot> simpleAdapter= new ArrayAdapter<Robot>(this, android.R.layout.simple_list_item_1, robots);
        CustomAdapter ca = new CustomAdapter(this, robots);
        lv.setAdapter(simpleAdapter);

        AdapterView.OnItemClickListener listClick = new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Intent intent = new Intent(MainActivity.this, ItemActivity.class);
                Robot r = robots.get(position);
                String name = r.getName();

                //This is where the magic happens: since Robot implements parcelable, 
                //you can simply add the robot object as an extra using putExtra().
                intent.putExtra("robot", r);
                startActivity(intent);
            }
        };
        lv.setOnItemClickListener(listClick);
    }
}

Second Activity (ItemActivity)

  • Uses Intent.getParcelableExtra() to retrieve the object data.
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class ItemActivity extends AppCompatActivity {
    TextView itemName;
    Button itemButton;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_item);
        itemButton = findViewById(R.id.itemButton1);
        itemButton.setText("Go Back");
        itemName = findViewById(R.id.itemName);
        Intent intent = getIntent();
        
        //Here is where the parcel is retrieved as a Robot object:
        Robot r = (Robot) intent.getParcelableExtra("robot");
        itemName.setText(r.getName() + ", motors: "+r.getMotors());
    }

    void clicked(View v){
        Intent intent = new Intent(this, MainActivity.class);
        startActivity(intent);
    }
}