Parcelable object that receives passed data coming

2019-09-07 18:05发布

问题:

I'm working on an Android app that stores contact information, I'm trying to add a feature that when you click on a contact item in the ListView it will send the contact object that implements parcelable over two the second activity.

This is Where I send the contact object over to the Contacts Activity. `

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
    // TODO Auto-generated method stub
    final Contact item = (Contact) getListAdapter().getItem(position);

    Intent updateIntent = new Intent(MainActivity.this, ContactsActivity.class);
    Bundle bundle = new Bundle();
    bundle.putParcelable("contact", item);
    updateIntent.putExtra(ContactsActivity.RECIVED_CONTACT, bundle);
    startActivityForResult(updateIntent,1);
    adapter.notifyDataSetChanged();
}`

This is in the onCreate of the Contacts Activity Class, this will check to see if any data was passed using the RECIVED_CONTACT tag. The line where I have an object of type Parcelable is where I have the errors, I'm getting a null pointer exception.

if (getIntent().getParcelableExtra(ContactsActivity.RECIVED_CONTACT) != null) {

    //This line is where the exception ouccurs
    Parcelable receivedContact = getIntent().getParcelableExtra("contact"); 
    updateContact(receivedContact);
}

My Contact object looks like this

public class Contact implements Parcelable {

String firstName;
String lastName;
String email;
String phone;

/**
 * Constructor
 */
public Contact(String firstName, String lastName, String email, String phone) {
    // TODO Auto-generated constructor stub
    this();
    this.firstName = firstName;
    this.lastName = lastName;
    this.email = email;
    this.phone = phone;
}

public Contact(Parcel parcel) {
    this.firstName = parcel.readString();
    this.lastName = parcel.readString();
    this.email = parcel.readString();
    this.phone = parcel.readString();
}

 // this is used to regenerate your object. All Parcelables must have a CREATOR that implements these two methods
    public static final Parcelable.Creator<Contact> CREATOR = new Parcelable.Creator<Contact>() {
        public Contact createFromParcel(Parcel in) {
            //return new Contact(in);
            Contact mContact = new Contact();
            mContact.firstName = in.readString();
            mContact.lastName = in.readString();
            mContact.email = in.readString();
            mContact.phone = in.readString();
            return mContact;
        }

        public Contact[] newArray(int size) {
            return new Contact[size];
        }

    };

    public Contact() {
        // TODO Auto-generated constructor stub
    }

    /**
     * @return the firstName
     */
    public String getFirstName() {
        return firstName;
    }

    /**
     * @return the lastName
     */
    public String getLastName() {
        return lastName;
    }

    /**
     * @return the email
     */
    public String getEmail() {
        return email;
    }

    /**
     * @return the phone
     */
    public String getPhone() {
        return phone;
    }

    public String toString() {
        return firstName + " \n" + lastName + " \n"
                + email + " \n" + phone + " \n\n";
    }

    @Override
    public int describeContents() {
        // TODO Auto-generated method stub
        return 0;
    }

    // write your object's data to the passed-in Parcel
    public void writeToParcel(Parcel out, int flags) {
        out.writeString(firstName);
        out.writeString(lastName);
        out.writeString(email);
        out.writeString(phone);
    }

}

I haven't been able to figure out how to fix this so if you want to see more of my code just ask and I will post it. I don't know much about Parcelable objects and I think that's why I've struggeled to do this.

I was however able to when clicking an add button in the MainActivity able to start a second ContactsActivity with some EditText fields for adding first and last names, email and phone I then put each of these four strings into a Contact object and send it back to the Main activity to be displayed. I haven't posted any of that code here because that code is working. I'm not able to figure out how to update one of the Contact objects already in the ListView.

I want to be able to take the contact object that is selected from the ListView send it to the ContactsActivity and put each of the four strings of data into the editText Fields.

回答1:

Okay, so when you're doing this:

Intent updateIntent = new Intent(MainActivity.this, ContactsActivity.class);
Bundle bundle = new Bundle();
bundle.putParcelable("contact", item);
updateIntent.putExtra(ContactsActivity.RECIVED_CONTACT, bundle);
startActivityForResult(updateIntent,1);
adapter.notifyDataSetChanged();

You end up with a data structure something like:

Intent {
    Bundle extras {
        Bundle bundle {
            Contact contact;
        }
    }
}

and when you retrieve it:

Parcelable receivedContact = getIntent().getParcelableExtra("contact"); 

You're not looking deeply enough. You're looking in the Intent.getExtras() bundle for a field named "contact", but you actually first need to retrieve the containing bundle that you put it in:

Bundle bundle = getIntent().getBundleExtra(ContactsActivity.RECEIVED_CONTACT);
Contact contact = bundle.getParcelableExtra("contact");

Alternately, just put the contact directly into the Intent's extras:

Intent updateIntent = new Intent(MainActivity.this, ContactsActivity.class);
updateIntent.putExtra(ContactsActivity.RECEIVED_CONTACT, item);

and retrieve with:

Contact contact = getIntent().getParcelableExtra(ContactsActivity.RECEIVED_CONTACT);