问题
I'm pretty new to Android programming and I've ran into this issue.
I have an object I am trying to send into a new activity, which is an instance of this class:
public final class BusinessEntity extends com.google.api.client.json.GenericJson {
/**
* The value may be {@code null}.
*/
@com.google.api.client.util.Key
private Contact contact;
/**
* The value may be {@code null}.
*/
@com.google.api.client.util.Key
@com.google.api.client.json.JsonString
private java.lang.Long id;
/**
* The value may be {@code null}.
*/
@com.google.api.client.util.Key
private java.lang.String imageUrl;
/**
* The value may be {@code null}.
*/
@com.google.api.client.util.Key
private Person owner;
/**
* The value may be {@code null}.
*/
@com.google.api.client.util.Key
private java.util.List<java.lang.String> tag;
/**
* The value may be {@code null}.
*/
@com.google.api.client.util.Key
private java.lang.String type;
I have tried converting it to gson and sending it in a Bundle with the Intent, and converting it back to a BusinessEntity in the new Activity The problem is I can't deserialize it in the new activity because it contains objects of an arbitrary type. I have tried parsing it as a JsonArray, but I get the exception: "IllegalStateException: This is not a JSON Array." I guess because the object is not in a collection.
There are a lot of attributes in the Person and Contact class that I would like to be able to access in the new Activity, but I would also like to avoid sending each attribute separately.
Here's what I have in the first class:
Intent i = new Intent(mActivity, DetailsActivity.class);
Bundle b = new Bundle();
Gson gson = new Gson();
String business = gson.toJson(businesses.get(position));
b.putString("business", business);
i.putExtras(b);
startActivity(i);
And here's what I have in the second class:
Bundle b = getIntent().getExtras();
String json = b.getString("business");
Gson gson = new Gson();
JsonParser parser = new JsonParser();
JsonArray array = parser.parse(json).getAsJsonArray();
Contact contact = gson.fromJson(array.get(0), Contact.class);
Long id = gson.fromJson(array.get(1), Long.class);
String imageURL = gson.fromJson(array.get(2), String.class);
Person person = gson.fromJson(array.get(3), Person.class);
List<String> tag = gson.fromJson(array.get(4), List.class);
But like I said I get a IllegalStateException at
JsonArray array = parser.parse(json).getAsJsonArray();
What is a good way to do this where I don't have to send each attribute separately?
--------------------------------------EDIT-------------------------------------------------------
I tried Parcelable, Serializable, Gson, everything... I was getting errors each time trying to cast the object back into a BusinessEntity in the new activity.
The workaround I created is I made a new class called SimpleBusiness that consists of all the attributes of BusinessEntity, Contact, and Person, implements Parcelable, and takes a BusinessEntity as a parameter in its constructor. I create a new SimpleBusiness object from the BusinessEntity I went to send to the new activity, send it with the intent, and get it from the intent from the new activity. It's kind of a weird workaround but it works perfectly.
Here is the new Class:
/**
* BusinessEntity class made with regular objects
*/
public class SimpleBusiness implements Parcelable {
//Contact
private String address1;
private String address2;
private String city;
private long contactID;
private String country;
private double latitude;
private double longitude;
private String phones;
private String postalCode;
private String province;
//BusinessEntity
private long id;
private String imageURL;
private List<String> tag;
private String type;
//Person
private String businessName;
private String firstName;
private String lastName;
private long personId;
/**
* Default no-argument constructor
*/
public SimpleBusiness(){
}
/**
* Constructor taking BusinessEntity as a parameter
* @param businessEntity
*/
public SimpleBusiness(BusinessEntity businessEntity) {
Contact contact = businessEntity.getContact();
Person person = businessEntity.getOwner();
address1 = contact.getAddress1();
address2 = contact.getAddress2();
city = contact.getCity();
contactID = contact.getContactId();
country = contact.getCountry();
latitude = contact.getLatitude();
longitude = contact.getLongitude();
phones = contact.getPhones();
postalCode = contact.getPostalCode();
province = contact.getProvince();
//BusinessEntity
id = businessEntity.getId();
imageURL = businessEntity.getImageUrl();
tag = businessEntity.getTag();
type = businessEntity.getType();
//Person
businessName = person.getBusinessName();
firstName= person.getFirstName();
lastName= person.getLastName();
personId= person.getPersonId();
}
public String getAddress1() {
return address1;
}
public void setAddress1(String address1) {
this.address1 = address1;
}
public String getAddress2() {
return address2;
}
public void setAddress2(String address2) {
this.address2 = address2;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public long getContactID() {
return contactID;
}
public void setContactID(long contactID) {
this.contactID = contactID;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public double getLatitude() {
return latitude;
}
public void setLatitude(double latitude) {
this.latitude = latitude;
}
public double getLongitude() {
return longitude;
}
public void setLongitude(double longitude) {
this.longitude = longitude;
}
public String getPhones() {
return phones;
}
public void setPhones(String phones) {
this.phones = phones;
}
public String getPostalCode() {
return postalCode;
}
public void setPostalCode(String postalCode) {
this.postalCode = postalCode;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getImageURL() {
return imageURL;
}
public void setImageURL(String imageURL) {
this.imageURL = imageURL;
}
public List<String> getTag() {
return tag;
}
public void setTag(List<String> tag) {
this.tag = tag;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getBusinessName() {
return businessName;
}
public void setBusinessName(String businessName) {
this.businessName = businessName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public long getPersonId() {
return personId;
}
public void setPersonId(long personId) {
this.personId = personId;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.address1);
dest.writeString(this.address2);
dest.writeString(this.city);
dest.writeLong(this.contactID);
dest.writeString(this.country);
dest.writeDouble(this.latitude);
dest.writeDouble(this.longitude);
dest.writeString(this.phones);
dest.writeString(this.postalCode);
dest.writeString(this.province);
dest.writeLong(this.id);
dest.writeString(this.imageURL);
dest.writeList(this.tag);
dest.writeString(this.type);
dest.writeString(this.businessName);
dest.writeString(this.firstName);
dest.writeString(this.lastName);
dest.writeLong(this.personId);
}
private SimpleBusiness(Parcel in) {
this.address1 = in.readString();
this.address2 = in.readString();
this.city = in.readString();
this.contactID = in.readLong();
this.country = in.readString();
this.latitude = in.readDouble();
this.longitude = in.readDouble();
this.phones = in.readString();
this.postalCode = in.readString();
this.province = in.readString();
this.id = in.readLong();
this.imageURL = in.readString();
this.tag = new ArrayList<String>();
in.readList(this.tag, List.class.getClassLoader());
this.type = in.readString();
this.businessName = in.readString();
this.firstName = in.readString();
this.lastName = in.readString();
this.personId = in.readLong();
}
public static final Creator<SimpleBusiness> CREATOR = new Creator<SimpleBusiness>() {
public SimpleBusiness createFromParcel(Parcel source) {
return new SimpleBusiness(source);
}
public SimpleBusiness[] newArray(int size) {
return new SimpleBusiness[size];
}
};
}
And the implementation:
Intent i = new Intent(mActivity, DetailsActivity.class);
Bundle b = new Bundle();
BusinessEntity business = businesses.get(position);
SimpleBusiness simpleBusiness = new SimpleBusiness(business);
i.putExtra("business", simpleBusiness);
//i.putExtras(b);
startActivity(i);
And in the DetailsActivity class:
Intent i = getIntent();
Bundle b = i.getExtras();
business = (SimpleBusiness)b.get("business");
Thanks for the help guys. It probably would have taken a lot longer if I didn't have the advice you guys gave me.
--------------------------------------------Edit 2--------------------------------------------
Switched to passing a BusinessEntity object directly with an EventBus. So much easier. http://www.stevenmarkford.com/passing-objects-between-android-activities/
Pass the object:
Intent i = new Intent(mActivity, DetailsActivity.class);
BusinessEntity business = businesses.get(position);
de.greenrobot.event.EventBus.getDefault().postSticky(business);
startActivity(i);
Retrieve the object: @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.busEntity = (BusinessEntity) EventBus.getDefault().removeStickyEvent(BusinessEntity.class);
setContentView(R.layout.activity_details);
}
回答1:
EventBus makes your life so much easier, see the example and links in my answer to this question: Saving information from one fragment and dialog if the user navigates to another fragment in essence, no need to do any serialization or anything, just put the object on the eventbus and grab it again anywhere in your code (in another Activity, Fragment, Service etc..)
回答2:
If you are able to modify BusinessEntity, then have it implement Serializable. You may then put the business as an extra:
//To put the object as an extra
...
BusinessEntity business = businesses(get(position));
Intent intent = new Intent(mActivity, DetailsActivity.class);
intent.putExtra("business", business); // Where business is now a `Serializable`
...
//To retrieve the object (in your second class).
//TODO -- Include check to see if intent has the extra first
BusinessEntity retrievedBusiness = (BusinessEntity) intent.getSerializableExtra("business")
回答3:
You should use Parcelable Objects https://github.com/codepath/android_guides/wiki/Using-Parcelable
回答4:
You can do this via Serializable interface. Just let your BusinessEntity implement Serializable, like this:
public final class BusinessEntity extends com.google.api.client.json.GenericJson implements Serializable {
//your code here
...
...
}
Then create your intent and put an extra to it:
Intent i = new Intent(mActivity, DetailsActivity.class);
i.putExtra("BusinessEntity", yourBuisnessEntityObject);
startActivity(i);
And finally in your DetailsActivity:
BusinessEntity business = (BusinessEntity) getIntent().getSerializableExtra("BusinessEntity");
Voila! You have your BusinessEntity object in DetailsActivity.
EDIT:
Back to your code, I think the problem is that you put a JsonObject extra not a JsonArray. You should do the same things that you posted firstly, but with one correction:
JsonObject object = parser.parse(json).getAsJsonObject(); and then parse it as JsonObject by keys.
来源:https://stackoverflow.com/questions/26600598/how-do-i-send-an-object-with-arbitrary-types-in-it-to-another-activity