0

I am trying to parcel some data from the main activity to another activity and present the data in a ListView. I have a single button in my MainActivity which creates and intent and ships the data to the other activity. However, as soon as I press the button the app crashes with BadParcelableException. Could somebody explain to me why this is happening?

This is my code in MainActivity:

public class MainActivity extends Activity {
private Button mButton;
public static String EXTRA_KEY = "key_extra";
private Person[] mPersons;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mPersons = new Person[1];

    mPersons[0] = new Person("GEORGI",23);
    mPersons[0] = new Person("Mariya",21);

    mButton = (Button) findViewById(R.id.parcelBTN);
    mButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(MainActivity.this,ReceiveParcelActivity.class);
            intent.putExtra(EXTRA_KEY,mPersons);
            startActivity(intent);
        }
    });
}

And this is the second Activity:

public class ReceiveParcelActivity extends ListActivity {
private Person[] mPersons;

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

    Intent intent = getIntent();
    Parcelable[] parcelables = intent.getParcelableArrayExtra(MainActivity.EXTRA_KEY);

    mPersons = Arrays.copyOf(parcelables,parcelables.length,Person[].class);

    ArrayAdapter<Person> adapter = new ArrayAdapter<Person>(this,android.R.layout.simple_list_item_1,mPersons);

    setListAdapter(adapter);
}

And this is the Person class which implements Parcelable interface

public class Person implements Parcelable {
private String mName;
private int mAge;

public Person(String name, int age) {
    mName = name;
    mAge = age;
}

public Person(Parcel parcel) {
    mName = parcel.readString();
    mAge = parcel.readInt();
}

@Override
public int describeContents() {
    return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(mName);
    dest.writeInt(mAge);
}

private static Creator<Person> CREATOR = new Creator<Person>() {
    @Override
    public Person createFromParcel(Parcel source) {
        return new Person(source);
    }

    @Override
    public Person[] newArray(int size) {
        return new Person[size];
    }
};
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Georgi Koemdzhiev
  • 11,421
  • 18
  • 62
  • 126

2 Answers2

0

I figured what was wrong. I declared the Creator private. After declaring it public it fixed the problem. However, now I don't know how to present the data into the ListActivity, I mean, now there is only one row and that is the memory address of the Person object. enter image description here

Georgi Koemdzhiev
  • 11,421
  • 18
  • 62
  • 126
0

Please try following this pattern, it rather implicitly defines all the fields specified within your class:

public class Person implements Parcelable {
    private String mName;
    private int mAge;

    public Person(String name, int age) {
        mName = name;
        mAge = age;
    }

    // ##### PARCELABLE ROUTINES #####
    private static final String KEY_NAME = "key_name";
    private static final String KEY_AGE = "key_age";

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        Bundle b = new Bundle();
        b.putString(KEY_NAME, mName);
        b.putInt(KEY_AGE, mAge);
        parcel.writeBundle(b);
    }

    public static final Parcelable.Creator<Person> CREATOR = new Creator<Person>() {
        @Override
        public Person createFromParcel(Parcel source) {
            Bundle b = source.readBundle();
            b.setClassLoader(getClass().getClassLoader());
            String name = b.getString(KEY_NAME);
            int age = b.getInt(KEY_AGE);

            return new Person(name, age);
        }

        @Override
        public Person[] newArray(int size) {
            return new Person[size];
        }
    };
}
dkarmazi
  • 3,199
  • 1
  • 13
  • 25
  • Thank you for your answer. However, I don't understand why we should use bundle. Sorry, I am new to android development, as you noticed and some thinks that are unfamiliar to me look strange. – Georgi Koemdzhiev May 22 '15 at 18:14
  • 1
    it's just a convenient way not to mess up with the types and their order, especially when your class grows significantly and you have many properties to process. However, of course you can also write Strings and Integers and other types straight to parcel object. – dkarmazi May 22 '15 at 18:20