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.
Related
This question already has answers here:
How can I make my custom objects Parcelable?
(11 answers)
Closed 6 years ago.
I am trying to learn parcelable .Earlier I was using get and set function but now I am using parcelable to pass the object to other class I made the passdata class and implemented the parcelable but how I can add the list to the class object.
class Passdata implements Parcelable {
private String title,album;
private long duration;
private Uri data,album_art;
public String getTitle() {
return title;
}
void setTitle(String title) {
this.title = title;
}
public String getAlbum() {
return album;
}
void setAlbum(String album) {
this.album = album;
}
public long getDuration() {
return duration;
}
void setDuration(long duration) {
this.duration = duration;
}
public Uri getData() {
return data;
}
void setData(Uri data) {
this.data = data;
}
public Uri getAlbum_art() {
return album_art;
}
void setAlbum_art(Uri album_art) {
this.album_art = album_art;
}
Passdata(Parcel in) {
title = in.readString();
album = in.readString();
duration = in.readLong();
data = in.readParcelable(Uri.class.getClassLoader());
album_art = in.readParcelable(Uri.class.getClassLoader());
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(title);
dest.writeString(album);
dest.writeLong(duration);
dest.writeParcelable(data, flags);
dest.writeParcelable(album_art, flags);
}
#Override
public int describeContents() {
return 0;
}
public static final Creator<Passdata> CREATOR = new Creator<Passdata>() {
#Override
public Passdata createFromParcel(Parcel in) {
return new Passdata(in);
}
#Override
public Passdata[] newArray(int size) {
return new Passdata[size];
}
};
}
how can I add the object like this
do {
int audioTitle = audioCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE);
int audioartist = audioCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST);
int audioduration = audioCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION);
int audiodata = audioCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
int audioalbum = audioCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM);
int audioalbumid = audioCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID);
Passdata info = new Passdata();
info.setData(Uri.parse(audioCursor.getString(audiodata)));
info.setTitle(audioCursor.getString(audioTitle));
info.setDuration(audioCursor.getLong(audioduration));
// info.setArtist(audioCursor.getString(audioartist));
info.setAlbum(audioCursor.getString(audioalbum));
info.setAlbum_art(ContentUris.withAppendedId(albumArtUri, audioCursor.getLong(audioalbumid)));
audioList.add(info);
}
I am getting error in the place were I am creating the passdata object
how to fix this??
You don't have empty constructor in PassData class. Add this code:
public Passdata() {
}
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 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 have two classes:
Driver Class:
public static final class Driver implements DriverColumns, BaseColumns, Parcelable {
public static final Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon().appendPath(PATH_DRIVERS).build();
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/com.test.console.drivers";
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.console.drivers";
private int driver_id, driver_number;
private String driver_name;
public Driver() {
}
public Driver(int driverID, int driverNumber, String driverName) {
this.setDriverID(driverID);
this.setDriverNumber(driverNumber);
this.setDriverName(driverName);
}
public static Uri buildDriverUri(String driverID) {
return CONTENT_URI.buildUpon().appendPath(driverID).build();
}
public int getDriverID() {
return driver_id;
}
public void setDriverID(int driver_id) {
this.driver_id = driver_id;
}
public int getDriverNumber() {
return driver_number;
}
public void setDriverNumber(int driver_number) {
this.driver_number = driver_number;
}
public String getDriverName() {
return driver_name;
}
public void setDriverName(String driver_name) {
this.driver_name = driver_name;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(driver_id);
dest.writeInt(driver_number);
dest.writeString(driver_name);
}
private Driver(Parcel in) {
this.driver_id = in.readInt();
this.driver_number = in.readInt();
this.driver_name = in.readString();
}
public static final Parcelable.Creator<Driver> CREATOR = new Parcelable.Creator<Driver>() {
#Override
public Driver createFromParcel(Parcel source) {
return new Driver(source);
}
#Override
public Driver[] newArray(int size) {
return new Driver[size];
}
};
}
and a Vehicle Class:
public static final class Vehicle implements VehicleColumns, BaseColumns, Parcelable {
public static final Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon().appendPath(PATH_VEHICLES).build();
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/com.test.console.vehicles";
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.console.vehicles";
private int vehicle_id, vehicle_number;
private String vehicle_vin;
public Vehicle() {
}
public Vehicle(int vehicleID, int vehicleNumber, String vehicleVin) {
setVehicleID(vehicleID);
setVehicleNumber(vehicleNumber);
setVehicleVin(vehicleVin);
}
public int getVehicleID() {
return vehicle_id;
}
public void setVehicleID(int mVehicleID) {
this.vehicle_id = mVehicleID;
}
public int getVehicleNumber() {
return vehicle_number;
}
public void setVehicleNumber(int mVehicleNumber) {
this.vehicle_number = mVehicleNumber;
}
public String getVehicleVin() {
return vehicle_vin;
}
public void setVehicleVin(String mVehicleVin) {
this.vehicle_vin = mVehicleVin;
}
public static Uri buildVehicleUri(String vehicleID) {
return CONTENT_URI.buildUpon().appendPath(vehicleID).build();
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(vehicle_id);
dest.writeInt(vehicle_number);
dest.writeString(vehicle_vin);
}
private Vehicle(Parcel in) {
this.vehicle_id = in.readInt();
this.vehicle_number = in.readInt();
this.vehicle_vin = in.readString();
}
public static final Parcelable.Creator<Vehicle> CREATOR = new Parcelable.Creator<Vehicle>() {
#Override
public Vehicle createFromParcel(Parcel source) {
return new Vehicle(source);
}
#Override
public Vehicle[] newArray(int size) {
return new Vehicle[size];
}
};
}
I'm trying to Link them together so I can use them in an ArrayList.
Basically Have a List of:
Driver + Vehicle
Not sure if I should have a superclass? Because i've read that we can't do something like this:
ArrayList<Driver,Vehicle> drivers_vehicles = new ArrayList<Driver,Vehicle>
I will need to Sort the list by driver_number in the Driver class.
How can I accomplish this?
Thanks..
You should make a new type uniting both driver and vehicle. I.e.
public class DriverVehiclePair implements Comparable<DriverVehiclePair> {
public Driver driver;
public Vehicle vehicle;
public int compareTo(DriverVehiclePair compareObject)
{
if (driver.driver_number < compareObject.driver_number)
return -1;
else if (driver_number == compareObject.driver_number)
return 0;
else
return 1;
}
...
}
Then you make a list of your new type and sort it like this
List<DriverVehiclePair> list = new ArrayList<DriverVehiclePair>();
// fill your list with data here (with proper arguments in constructors - I don't send any data below
list.add(new DriverVehiclePair(new Driver(), new Vehicle()));
// and finally sort it
Collections.sort(list);
You might want to take a read on Comparable interface
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();
}