Search code examples
androidandroid-intentandroid-activitycastingparcelable

Getting the Wrong Object type through Parcelable


I have two Classes that implement Parcelable. I am trying to pass an object of each class through an intent to an activity. However, when I try to access one of the objects, it thinks that it is the type of the other object and tries to cast it.

The First Class

public class Track implements Parcelable{

private String trackOwner;
private String trackName;
private Double sumDistace;

public final static String POINTTOPOINT = "POINTTOPOINT";
public final static String CIRCUIT = "CIRCUIT";

private String trackType;
private ArrayList<Checkpoint> checkpoints;

public Track(String trackOwner, String trackName, String trackType, Double sumDistace){

    this.trackOwner = trackOwner;
    this.trackName = trackName;
    this.trackType = trackType;
    checkpoints = new ArrayList<Checkpoint>();
    this.sumDistace = sumDistace;

}

public Track(){

}

public Track(Parcel in){
    readFromParcel(in);
}

public static final Parcelable.Creator CREATOR = new Parcelable.Creator(){

    @Override
    public Object createFromParcel(Parcel source) {
        return new User(source);
    }

    @Override
    public Object[] newArray(int size) {
        return new User[size];
    }
};

public String getTrackOwner(){
    return this.trackOwner;
}

public String getTrackName(){
    return this.trackName;
}

public String getTrackType(){
    return this.trackType;
}

public Double getSumDistace(){return this.sumDistace; }

public void setCheckpoints(ArrayList<Checkpoint> checkpoints){
    this.checkpoints = checkpoints;
}

public void setSumDistace(double sumDistace){
    this.sumDistace = sumDistace;
}

public void addCheckpoint(Checkpoint checkpoint){
    checkpoints.add(checkpoint);
}

public ArrayList<Checkpoint> getCheckpoints(){
    return this.checkpoints;
}


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

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(trackOwner);
    dest.writeString(trackName);
    dest.writeString(trackType);
    dest.writeTypedList(checkpoints);
    dest.writeDouble(sumDistace);

}

public void readFromParcel(Parcel in){
    trackOwner = in.readString();
    trackName = in.readString();
    trackType = in.readString();
    in.readTypedList(checkpoints,Checkpoint.CREATOR);
    sumDistace = in.readDouble();
}
}

The Second Class

public class User implements Parcelable{

private String email;
private String racername;
private ArrayList<String> friendsList;
private ArrayList<String> vehicleList;
private ArrayList<String> trackList;



private double latPos;
private double longPos;



public User(String racername, String email){
    this.email = email;
    this.racername = racername;
    friendsList = new ArrayList<String>();
    vehicleList = new ArrayList<String>();
    trackList = new ArrayList<String>();
}

public User(){

}

public User(Parcel in){
    readFromParcel(in);
}

public static final Parcelable.Creator CREATOR = new Parcelable.Creator(){

    @Override
    public Object createFromParcel(Parcel source) {
        return new User(source);
    }

    @Override
    public Object[] newArray(int size) {
        return new User[size];
    }
};

public String getEmail(){
    return email;
}
public String getRacername(){
    return racername;
}
public ArrayList<String> getfriendsList(){
    return friendsList;
}
public ArrayList<String> getVehicleList(){
    return vehicleList;
}
public ArrayList<String> getTrackList() { return trackList; }
public double getLatPos(){
    return latPos;
}
public double getLongPos(){
    return longPos;
}


public String addFriend(String newFriend){
    String returnMessage = "";
    if(friendsList == null){
        friendsList = new ArrayList<String>();
        friendsList.add(newFriend);
    } else {
        if(friendsList.contains(newFriend)){
            returnMessage = "That friend already exists";
        } else {
            friendsList.add(newFriend);
            returnMessage = "Friend added!";
        }
    }
    return returnMessage;
}

public String deleteFriend(String oldFriend){
    String returnMessage = "";
    if(friendsList.contains(oldFriend)) {
        friendsList.remove(oldFriend);
        returnMessage = "Friend Removed";
    } else {
        returnMessage = "Friend not found.";
    }
    return returnMessage;
}

public void addTrack(String trackName){
    if(trackList==null){
        trackList = new ArrayList<String>();
    }
    trackList.add(trackName);
}


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

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(email);
    dest.writeString(racername);
    dest.writeStringList(friendsList);
    dest.writeStringList(vehicleList);
    dest.writeStringList(trackList);

    dest.writeDouble(latPos);
    dest.writeDouble(longPos);


}

public void readFromParcel(Parcel in){
    email = in.readString();
    racername = in.readString();
    friendsList = in.createStringArrayList();
    vehicleList = in.createStringArrayList();
    trackList = in.createStringArrayList();


    latPos = in.readDouble();
    longPos = in.readDouble();

}
}

Creating the two objects. Passing them into an intent and starting the activity. The user object is obtained from a previous intent, so I'm unsure if thats whats giving me the error. HostRace is true.

final Track newTrack;
            if(trackType.equals(Track.CIRCUIT)){
                newTrack = new 
Track(racername,trackName,Track.CIRCUIT,sumDistance);

            } else {
                newTrack = new Track(racername,trackName,Track.POINTTOPOINT,sumDistance);
            }
            newTrack.setCheckpoints(checkpoints);
            String trackKey = racername + "," + trackName;
            Log.d("Track key: ", trackKey);

            ssDB.child("tracks").child(trackKey).setValue(newTrack).addOnCompleteListener(new OnCompleteListener<Void>() {
                @Override
                public void onComplete(@NonNull Task<Void> task) {
                    if(task.isSuccessful()){
                        user.addTrack(trackName);
                        ssDB.child("users").child(user.getRacername()).child("trackList").setValue(user.getTrackList()).addOnCompleteListener(new OnCompleteListener<Void>() {
                            @Override
                            public void onComplete(@NonNull Task<Void> task) {
                                if(task.isSuccessful()){
                                    Toast.makeText(CreateTrackActivity2.this,"Track Created!",Toast.LENGTH_LONG).show();
                                    if(hostRace){

                                        intentToHostRaceActivity.putExtra("user",user);
                                        intentToHostRaceActivity.putExtra("track",newTrack);
                                        startActivity(intentToHostRaceActivity);
                                    } else {
                                        intentToHomeActivity.putExtra("user",user);
                                        startActivity(intentToHomeActivity);
                                    }
                                }
                            }
                        });


                    }
                }
            });

The intent in the other class where recieving the intent.

Track track = getIntent().getExtras().getParcelable("track");
User user = getIntent().getExtras().getParcelable("user");

The exception I recieved

04-04 23:34:51.725 27284-27284/com.illbirdstudios.illbird.streetsend D/Exception:: java.lang.ClassCastException: com.illbirdstudios.illbird.streetsend.User cannot be cast to com.illbirdstudios.illbird.streetsend.Track

Solution

  • Try this

    public static final Parcelable.Creator CREATOR = new Parcelable.Creator(){
    
        @Override
        public Object createFromParcel(Parcel source) {
            return new Track(source);
        }
    
        @Override
        public Object[] newArray(int size) {
            return new Track[size];
        }
    };