Let say I have 2 class ChildModel and ParentModel
public class ParentModel implements Parcelable {
private int id;
private String value;
private ArrayList<ChildModel> childs;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String toString() {
return String.format("%s %d %s", "[PARENT]", id, value);
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public ArrayList<ChildModel> getChilds() {
return childs;
}
public void setChilds(ArrayList<ChildModel> childs) {
this.childs = childs;
}
public ParentModel() {
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(this.id);
dest.writeString(this.value);
}
protected ParentModel(Parcel in) {
this.id = in.readInt();
this.value = in.readString();
}
public static final Creator<ParentModel> CREATOR = new Creator<ParentModel>() {
public ParentModel createFromParcel(Parcel source) {
return new ParentModel(source);
}
public ParentModel[] newArray(int size) {
return new ParentModel[size];
}
};
}
and
public class ChildModel implements Parcelable {
private int id;
private String value;
private ParentModel parent;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public ParentModel getParent() {
return parent;
}
public void setParent(ParentModel parent) {
this.parent = parent;
}
public String toString(){
return String.format("%s %d %s", "[CHILD]", id, value);
}
public ChildModel() {
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(this.id);
dest.writeString(this.value);
dest.writeParcelable(this.parent, 0);
}
protected ChildModel(Parcel in) {
this.id = in.readInt();
this.value = in.readString();
this.parent = in.readParcelable(ParentModel.class.getClassLoader());
}
public static final Creator<ChildModel> CREATOR = new Creator<ChildModel>() {
public ChildModel createFromParcel(Parcel source) {
return new ChildModel(source);
}
public ChildModel[] newArray(int size) {
return new ChildModel[size];
}
};
}
When passing ArrayList of 2 ChildModel into the second activity, although in Activity 1, these 2 ChildModel have the same ParentModel, but here these 2 have 2 different ParentModel (the same value for each field in the ParentModel). So anyone know how to fix this ?
To be more general, is there any mechanic that allow when write the same object into parcel twice, it would only point to the same memory in the Parcel ?
Related
I have an object with a couple of Strings, one int and another object which has 4 inner objects. All of them implementing Parcelable. In order to generate the boilerplate code, I used Parcelable plugin from Android studio.
Even though all the objects are parcelable, I'm getting the following error: android.os.BadParcelableException: ClassNotFoundException when unmarshalling: AlbumTrackResponse
Here's how the POJOs look like:
Main object:
public class AlbumTrackResponse implements Parcelable {
private String id;
private String albumId;
private String position;
private String title;
private int rate;
private AllServices services;
public AllServices getServices() {
return services;
}
public void setServices(AllServices services) {
this.services = services;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getAlbumId() {
return albumId;
}
public void setAlbumId(String albumId) {
this.albumId = albumId;
}
public String getPosition() {
return position;
}
public void setPosition(String position) {
this.position = position;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getRate() {
return rate;
}
public void setRate(int rate) {
this.rate = rate;
}
protected AlbumTrackResponse(Parcel in) {
id = in.readString();
albumId = in.readString();
position = in.readString();
title = in.readString();
rate = in.readInt();
services = (AllServices) in.readValue(AllServices.class.getClassLoader());
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(id);
dest.writeString(albumId);
dest.writeString(position);
dest.writeString(title);
dest.writeInt(rate);
dest.writeValue(services);
}
#SuppressWarnings("unused")
public static final Parcelable.Creator<AlbumTrackResponse> CREATOR = new Parcelable.Creator<AlbumTrackResponse>() {
#Override
public AlbumTrackResponse createFromParcel(Parcel in) {
return new AlbumTrackResponse(in);
}
#Override
public AlbumTrackResponse[] newArray(int size) {
return new AlbumTrackResponse[size];
}
};
}
Inner object with 4 objects
public class AllServices implements Parcelable {
private GigRevService gigrev;
private AppleService apple;
private GoogleService google;
private SpotifyService spotify;
protected AllServices(Parcel in) {
gigrev = (GigRevService) in.readValue(GigRevService.class.getClassLoader());
apple = (AppleService) in.readValue(AppleService.class.getClassLoader());
google = (GoogleService) in.readValue(GoogleService.class.getClassLoader());
spotify = (SpotifyService) in.readValue(SpotifyService.class.getClassLoader());
}
#Override
public int describeContents() {
return 0;
}
public GigRevService getGigrev() {
return gigrev;
}
public void setGigrev(GigRevService gigrev) {
this.gigrev = gigrev;
}
public AppleService getApple() {
return apple;
}
public void setApple(AppleService apple) {
this.apple = apple;
}
public GoogleService getGoogle() {
return google;
}
public void setGoogle(GoogleService google) {
this.google = google;
}
public SpotifyService getSpotify() {
return spotify;
}
public void setSpotify(SpotifyService spotify) {
this.spotify = spotify;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeValue(gigrev);
dest.writeValue(apple);
dest.writeValue(google);
dest.writeValue(spotify);
}
#SuppressWarnings("unused")
public static final Parcelable.Creator<AllServices> CREATOR = new Parcelable.Creator<AllServices>() {
#Override
public AllServices createFromParcel(Parcel in) {
return new AllServices(in);
}
#Override
public AllServices[] newArray(int size) {
return new AllServices[size];
}
};
}
The inner objects from here contain just string items.
Here's how I pass the ArrayList to the bundle:
bundle.putParcelableArrayList(MediaPlayerService.TRACK_LIST, trackList);
I'm passing the items from an Activity to a Service. Any ideas why I'm getting this error?
EDIT: Implementation of service classes
public class GoogleService implements Parcelable {
private String name;
private String uri;
public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
protected GoogleService(Parcel in) {
name = in.readString();
uri = in.readString();
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeString(uri);
}
#SuppressWarnings("unused")
public static final Parcelable.Creator<GoogleService> CREATOR = new Parcelable.Creator<GoogleService>() {
#Override
public GoogleService createFromParcel(Parcel in) {
return new GoogleService(in);
}
#Override
public GoogleService[] newArray(int size) {
return new GoogleService[size];
}
};
}
This looks extremly strange
this.services = in.readParcelable(getClass().getClassLoader());
You are pointing out to the wrong class loader. You have to use it like this
this.services = (AllServices)in.readParcelable(AllServices.class.getClassLoader());
Besides that, I am always using this site http://www.parcelabler.com/ to quickly generate my Parceables. Or you could use it like this
services = (AllServices) in.readValue(AllServices.class.getClassLoader());
Here:
protected AllServices(Parcel in) { this.gigrev = in.readParcelable(getClass().getClassLoader());
this.apple = in.readParcelable(getClass().getClassLoader());
this.google = in.readParcelable(getClass().getClassLoader());
this.spotify = in.readParcelable(getClass().getClassLoader()); }
Replace it with
protected AllServices(Parcel in) { this.gigrev = in.readParcelable(GigRevService.class.getClassLoader());
this.apple = in.readParcelable(AppleService.class.getClassLoader());
this.google = in.readParcelable(GoogleService.class.getClassLoader());
this.spotify = in.readParcelable(SpotifyService.class.getClassLoader()); }
And replace:
this.services = in.readParcelable(getClass().getClassLoader());
With:
this.services = in.readParcelable(AllServices.class.getClassLoader());
Also can you show the GoogleService etc classes? Each inner object's class must have a Parcelable creator also and implement the Parcelable interface as well.
Folks, I'm getting mad with parcelables.
Here goes, I have these lines:
Intent i = new Intent(context, PaymentDetailsActivity.class);
i.putExtra(ConstantsUtils.PARAM_INTENT_ORDER_DETAILS, responseOrderInfoApiModel);
i.putExtra(ConstantsUtils.PARAM_INTENT_PAYMENT_INFO, paymentInfoViewModel);
startActivity(i);
and here I receive my parcelables:
Intent receivedIntent = getIntent();
responseOrderInfoApiModel = receivedIntent.getParcelableExtra(ConstantsUtils.PARAM_INTENT_ORDER_DETAILS);
paymentInfoViewModel = receivedIntent.getParcelableExtra(ConstantsUtils.PARAM_INTENT_PAYMENT_INFO);
The point is, responseOrderInfoApiModel is receiving a null, but it shouldn't, however if I comment the line:
i.putExtra(ConstantsUtils.PARAM_INTENT_PAYMENT_INFO, paymentInfoViewModel);
My responseOrderInfoApiModel receive the correct value.
Here goes my parcelables:
ResponseOrderInfoApiModel -
public class ResponseOrderInfoApiModel implements Parcelable{
private String cardNumber;
private double total;
private ArrayList<ResponseOrderItemApiModel> listItem;
public ResponseOrderInfoApiModel() {
}
public ResponseOrderInfoApiModel(Parcel source) {
if(listItem == null){
listItem = new ArrayList<>();
}
setCardNumber(source.readString());
setTotal(source.readDouble());
source.readTypedList(listItem, ResponseOrderItemApiModel.CREATOR);
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(cardNumber);
dest.writeDouble(total);
dest.writeTypedList(listItem);
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
#Override
public ResponseOrderInfoApiModel createFromParcel(Parcel source) {
return new ResponseOrderInfoApiModel(source);
}
#Override
public ResponseOrderInfoApiModel[] newArray(int size) {
return new ResponseOrderInfoApiModel[size];
}
};
#Override
public int describeContents() {
return 0;
}
public ArrayList<ResponseOrderItemApiModel> getListItem() {
return listItem;
}
public void setListItem(ArrayList<ResponseOrderItemApiModel> listItem) {
this.listItem = listItem;
}
public String getCardNumber() {
return cardNumber;
}
public void setCardNumber(String cardNumber) {
this.cardNumber = cardNumber;
}
public double getTotal() {
return total;
}
public void setTotal(double total) {
this.total = total;
}
}
ResponseOrderItemApiModel (is a arrayList in ResponseOrderInfoApiModel) -
public class ResponseOrderItemApiModel implements Parcelable {
private String description;
private int quantity;
private double total;
private double unitPrice;
public ResponseOrderItemApiModel() {
}
public ResponseOrderItemApiModel(Parcel source) {
setDescription(source.readString());
setQuantity(source.readInt());
setTotal(source.readDouble());
setUnitPrice(source.readDouble());
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(description);
dest.writeInt(quantity);
dest.writeDouble(total);
dest.writeDouble(unitPrice);
}
public static Parcelable.Creator<ResponseOrderItemApiModel> CREATOR = new Parcelable.Creator<ResponseOrderItemApiModel>(){
#Override
public ResponseOrderItemApiModel createFromParcel(Parcel source) {
return new ResponseOrderItemApiModel(source);
}
#Override
public ResponseOrderItemApiModel[] newArray(int size) {
return new ResponseOrderItemApiModel[size];
}
};
#Override
public int describeContents() {
return 0;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
public double getTotal() {
return total;
}
public void setTotal(double total) {
this.total = total;
}
public double getUnitPrice() {
return unitPrice;
}
public void setUnitPrice(double unitPrice) {
this.unitPrice = unitPrice;
}
}
PaymentInfoViewModel -
public class PaymentInfoViewModel implements Parcelable {
private long idEstablishment;
private String nameEstablishment;
private int cardNumber;
private double cardSubTotalValue;
private double cardTotalValue;
private byte tipPercentage;
private long idCardPayment;
public PaymentInfoViewModel() {
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
#Override
public PaymentInfoViewModel createFromParcel(Parcel source) {
return new PaymentInfoViewModel(source);
}
#Override
public PaymentInfoViewModel[] newArray(int size) {
return new PaymentInfoViewModel[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(idEstablishment);
dest.writeString(nameEstablishment);
dest.writeInt(cardNumber);
dest.writeDouble(cardSubTotalValue);
dest.writeDouble(cardTotalValue);
dest.writeByte(tipPercentage);
dest.writeLong(idCardPayment);
}
public PaymentInfoViewModel(Parcel source) {
setIdEstablishment(source.readLong());
setNameEstablishment(source.readString());
setCardNumber(source.readInt());
setCardSubTotalValue(source.readDouble());
setCardTotalValue(source.readDouble());
setTipPercentage(source.readByte());
setIdCardPayment(idCardPayment);
}
public long getIdEstablishment() {
return idEstablishment;
}
public void setIdEstablishment(long idEstablishment) {
this.idEstablishment = idEstablishment;
}
public String getNameEstablishment() {
return nameEstablishment;
}
public void setNameEstablishment(String nameEstablishment) {
this.nameEstablishment = nameEstablishment;
}
public int getCardNumber() {
return cardNumber;
}
public void setCardNumber(int cardNumber) {
this.cardNumber = cardNumber;
}
public double getCardTotalValue() {
return cardTotalValue;
}
public void setCardTotalValue(double cardTotalValue) {
this.cardTotalValue = cardTotalValue;
}
public byte getTipPercentage() {
return tipPercentage;
}
public void setTipPercentage(byte tipPercentage) {
this.tipPercentage = tipPercentage;
}
public double getCardSubTotalValue() {
return cardSubTotalValue;
}
public void setCardSubTotalValue(double cardSubTotalValue) {
this.cardSubTotalValue = cardSubTotalValue;
}
public long getIdCardPayment() {
return idCardPayment;
}
public void setIdCardPayment(long idCardPayment) {
this.idCardPayment = idCardPayment;
}
}
Try using bundle and put your data in bundle and then put bundle in to intent. Once i had such a funny problem and this method solved my problem.
I am sending an object from an antivity to other. the class is:
public class Reparacion implements Parcelable {
private int tipo;
private int estado;
private int id;
private String razonSocial;
private String direccion;
private String contacto;
private String telefono;
private String detalle;
public Reparacion() {
}
public Reparacion(int tipo, int estado, int id, String razSoc, String dir,
String contacto, String tfno, String detalle) {
this.tipo = tipo;
this.estado = estado;
this.id = id;
this.razonSocial = razSoc;
this.direccion = dir;
this.contacto = contacto;
this.telefono = tfno;
this.detalle = detalle;
}
public String getContacto() {
return contacto;
}
public void setContacto(String contacto) {
this.contacto = contacto;
}
public String getTelefono() {
return telefono;
}
public void setTelefono(String telefono) {
this.telefono = telefono;
}
public String getDetalle() {
return detalle;
}
public void setDetalle(String detalle) {
this.detalle = detalle;
}
public int getTipo() {
return tipo;
}
public void setTipo(int tipo) {
this.tipo = tipo;
}
public String getRazonSocial() {
return razonSocial;
}
public void setRazonSocial(String razonSocial) {
this.razonSocial = razonSocial;
}
public String getDireccion() {
return direccion;
}
public void setDireccion(String direccion) {
this.direccion = direccion;
}
public int getEstado() {
return estado;
}
public void setEstado(int estado) {
this.estado = estado;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(this.tipo);
dest.writeInt(this.estado);
dest.writeLong(this.id);
dest.writeString(this.razonSocial);
dest.writeString(this.direccion);
dest.writeString(this.contacto);
dest.writeString(this.telefono);
dest.writeString(this.detalle);
}
public Reparacion(Parcel in) {
readFromParcel(in);
}
private void readFromParcel(Parcel in) {
this.tipo = in.readInt();
this.estado = in.readInt();
this.id = in.readInt();
this.razonSocial = in.readString();
this.direccion = in.readString();
this.contacto = in.readString();
this.telefono = in.readString();
this.detalle = in.readString();
}
public static final Parcelable.Creator<Reparacion> CREATOR = new Parcelable.Creator<Reparacion>() {
public Reparacion createFromParcel(Parcel in) {
return new Reparacion(in);
}
public Reparacion[] newArray(int size) {
return new Reparacion[size];
}
};
public void almacenar(Context contexto){
ReparacionBBDD rbd=new ReparacionBBDD(contexto);
rbd.insert(this);
}
public void eliminar(Context contexto){
ReparacionBBDD rbd=new ReparacionBBDD(contexto);
rbd.delete(this);
}
public void actualizar(Context contexto){
ReparacionBBDD rbd=new ReparacionBBDD(contexto);
rbd.update(this);
}
}
The problem is that I can recovery the int data, but the string data is null when I received the object. how is it possible???
I have read a lot of codes, and I have do it a lot of times, but I don't know the mistake!!
very thanks!!!
You must retrieve data as the way (data-type & order) you added. So this line can cause the issue:
dest.writeLong(this.id);
Replace that with:
dest.writeInt(this.id);
I am currently trying to pass a parceablearraylist from mylogin activity to my main activity but getting a
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.muuves.introround/com.muuves.introround.activities.MainActivity}: java.lang.RuntimeException: Parcel android.os.Parcel#41ef90a8: Unmarshalling unknown type code 7536741 at offset 684
Here are my parceable objects
public class Challenge implements Parcelable {
private Integer id;
private Integer challenger_id;
private Integer friend_id;
private String artist_name;
private String song_name;
private String image_url;
private String song_url;
private String answer_url;
private int challenge_attempts_left;
private int answer;
private Person person;
private Person friend;
public Challenge() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getChallenger_id() {
return challenger_id;
}
public void setChallenger_id(Integer challenger_id) {
this.challenger_id = challenger_id;
}
public Integer getFriend_id() {
return friend_id;
}
public void setFriend_id(Integer friend_id) {
this.friend_id = friend_id;
}
public String getArtist_name() {
return artist_name;
}
public void setArtist_name(String artist_name) {
this.artist_name = artist_name;
}
public String getSong_name() {
return song_name;
}
public void setSong_name(String song_name) {
this.song_name = song_name;
}
public String getImage_url() {
return image_url;
}
public void setImage_url(String image_url) {
this.image_url = image_url;
}
public String getSong_url() {
return song_url;
}
public void setSong_url(String song_url) {
this.song_url = song_url;
}
public String getAnswer_url() {
return answer_url;
}
public void setAnswer_url(String answer_url) {
this.answer_url = answer_url;
}
public int getChallenge_attempts_left() {
return challenge_attempts_left;
}
public void setChallenge_attempts_left(int challenge_attempts_left) {
this.challenge_attempts_left = challenge_attempts_left;
}
public int getAnswer() {
return answer;
}
public void setAnswer(int answer) {
this.answer = answer;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
public Person getFriend() {
return friend;
}
public void setFriend(Person friend) {
this.friend = friend;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeInt(challenger_id);
dest.writeInt(friend_id);
dest.writeString(artist_name);
dest.writeString(image_url);
dest.writeString(song_url);
dest.writeString(answer_url);
dest.writeInt(challenge_attempts_left);
dest.writeInt(answer);
dest.writeParcelable(person, flags);
dest.writeParcelable(friend, flags);
}
public static final Parcelable.Creator<Challenge> CREATOR = new Parcelable.Creator<Challenge>() {
#Override
public Challenge createFromParcel(Parcel in) {
Challenge challenge = new Challenge();
challenge.setId(in.readInt());
challenge.setChallenger_id(in.readInt());
challenge.setFriend_id(in.readInt());
challenge.setArtist_name(in.readString());
challenge.setSong_name(in.readString());
challenge.setImage_url(in.readString());
challenge.setSong_url(in.readString());
challenge.setAnswer_url(in.readString());
challenge.setChallenge_attempts_left(in.readInt());
challenge.setAnswer(in.readInt());
challenge.setPerson((Person) in.readParcelable(Person.class.getClassLoader()));
challenge.setFriend((Person) in.readParcelable(Person.class.getClassLoader()));
return challenge;
}
#Override
public Challenge[] newArray(int size) {
return new Challenge[size];
}
};
}
public class Person implements Parcelable {
private int id;
private String first_name;
private String last_name;
private String image_url;
public Person(){
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getFirst_Name() {
return first_name;
}
public void setFirst_Name(String first_name) {
this.first_name = first_name;
}
public String getLast_Name() {
return last_name;
}
public void setLast_Name(String last_name) {
this.last_name = last_name;
}
public String getImage_url() {
return image_url;
}
public void setImage_url(String image_url) {
this.image_url = image_url;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeString(first_name);
dest.writeString(last_name);
dest.writeString(image_url);
}
public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>() {
#Override
public Person createFromParcel(Parcel in) {
Person person = new Person();
person.setId(in.readInt());
person.setFirst_Name(in.readString());
person.setLast_Name(in.readString());
person.setImage_url(in.readString());
return person;
}
#Override
public Person[] newArray(int size) {
return null;
}
};
}
Login activity
#Override
public void preLoadDetails(Details details) {
Intent intent = new Intent(this, MainActivity.class);
Bundle bundle = new Bundle();
bundle.putParcelableArrayList("receive", details.getReceive());
intent.putExtras(bundle);
startActivity(intent);
}
MainActivity
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle bundle = this.getIntent().getExtras();
ArrayList<Challenge> friends = bundle.getParcelableArrayList("receive");
mContent = new MainFragment(0);
mContent.setArguments(getIntent().getExtras());
// set the Above View
setContentView(R.layout.home_frame);
getSupportFragmentManager().beginTransaction()
.replace(R.id.content_frame, mContent).commit();
// set the Behind View
setBehindContentView(R.layout.menu_frame);
getSupportFragmentManager().beginTransaction()
.replace(R.id.menu_frame, new MenuFragment()).commit();
// Disable
getSlidingMenu().setTouchModeAbove(SlidingMenu.TOUCHMODE_NONE);
}
Been trying to fix it for the pass day and getting no where all I know is that person parceable object in the challenge object are always null but they are not when I put them in the bundle.
Appreciate any input.
Those Integer type could be null or an int, you need to handle that situation properly.
For example I have utility functions like this :
static public Integer readInteger(Parcel in){
if(in.readInt() == 1){
return in.readInt();
}else{
return null;
}
}
static public void writeInteger(Integer value, Parcel out){
if(value != null){
out.writeInt(1);
out.writeInt(value);
}else{
out.writeInt(0);
}
}
First thing in the class Challenge you use Integer attributes and you parce "int" those are 2 diferents things.
Exemple of how i do things myself :
public Podcast(Parcel parcel) {
id = parcel.readLong();
title = parcel.readString();
subtitle = parcel.readString();
summary = parcel.readString();
duration = parcel.readString();
author = parcel.readString();
date = parcel.readString();
mp3 = parcel.readString();
podcastCategoryId = parcel.readLong();
}
#Override
public int describeContents() {
// not used
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(id);
dest.writeString(title);
dest.writeString(subtitle);
dest.writeString(summary);
dest.writeString(duration);
dest.writeString(author);
dest.writeString(date);
dest.writeString(mp3);
dest.writeLong(podcastCategoryId);
}
public static Creator<Podcast> CREATOR = new Creator<Podcast>() {
public Podcast createFromParcel(Parcel parcel) {
return new Podcast(parcel);
}
public Podcast[] newArray(int size) {
return new Podcast[size];
}
};
#Override
public Person[] newArray(int size) {
return null;
}
You should create there an array of that size and return it.
#Override
public Person[] newArray(int size) {
return new Person[size];
}
Solved it was actually very simple, forgot song url when i was writing to the parcel. Any when i missed that write that was why i was getting the weird exception for person object. it was expecting a person object but was getting something else. 1 day wasted oh well :(
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeInt(challenger_id);
dest.writeInt(friend_id);
dest.writeString(artist_name);
**dest.writeString(song_name);**
dest.writeString(image_url);
dest.writeString(song_url);
dest.writeString(answer_url);
dest.writeInt(challenge_attempts_left);
dest.writeInt(answer);
dest.writeParcelable(person, flags);
dest.writeParcelable(friend, flags);
}
I'm trying to parcel an object which contains some string/int variables and an object variable. The strings and int's are working, but not the nested object. I understand I would have to it also parcelable, but I'm apparently doing something wrong=. In my nested class, the writeToParcel method gets called (I check with a Log.d() call), but the createFromParcel() doesn't. I end up getting a null object. This is my simplified code:
public class MyClass implements Parcelable {
public MyClass() {
}
private Integer id;
private String name;
private MyOtherClass otherClass = new MyOtherClass();
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public OtherClass getOtherClass() {
return otherClass;
}
public void setOtherClass(OtherClass otherClass) {
this.otherClass = otherClass;
}
public static final Parcelable.Creator<MyClass> CREATOR
= new Parcelable.Creator<MyClass>() {
public MyClass createFromParcel(Parcel in) {
return new MyClass(in);
}
public MyClass[] newArray(int size) {
return new MyClass[size];
}
};
#Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(id);
dest.writeParcelable(otherClass, flags);
}
private MyClass(Parcel in) {
name = in.readString();
id = in.readInt();
otherClass = (OtherClass) in.readParcelable(OtherClass.class.getClassLoader());
}
}
class MyOtherClass implements Parcelable {
public OtherClass() {
}
private String resourcePreviewURL;
public String getResourcePreviewURL() {
return resourcePreviewURL;
}
public void setResourcePreviewURL(String resourcePreviewURL) {
this.resourcePreviewURL = resourcePreviewURL;
}
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel out, int flags) {
Log.d("parcel", "write to parcel"); // this gets called
out.writeString(resourcePreviewURL);
}
public static final Parcelable.Creator<MyOtherClass> CREATOR
= new Parcelable.Creator<MyOtherClass>() {
public MyOtherClass createFromParcel(Parcel in) {
Log.d("parcel", "create from parcel"); // this doesn't get called
return new MyOtherClass(in);
}
public ResourcePreviews[] newArray(int size) {
return new ResourcePreviews[size];
}
};
private OtherClass(Parcel in) {
Log.d("parcel", "read from parcel"); // this doesn't get called
resourcePreviewURL = in.readString();
}
}
I solved this by changing the order in which I write/read from the Parcel. I made the dest.writeParcelable(otherClass, flags); and the otherClass = (OtherClass) in.readParcelable(OtherClass.class.getClassLoader()); calls to be the first in their methods and it started working. Is that an issue?
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(otherClass, flags);
dest.writeString(name);
dest.writeInt(id);
}
private MyClass(Parcel in) {
otherClass = (OtherClass) in.readParcelable(OtherClass.class.getClassLoader());
name = in.readString();
id = in.readInt();
}