3

This is an extension for Android implement Parcelable object which has hashmap but mine is a little different.

I have these classes

public class EventDetails implements Parcelable {
    Private String id;
    Private String eventName;
    Private Long eventUnixTime;
    Private HashMap <String, User> pickedUser = null;
}

and

public class User implements Parcelable {
    private String email;
    private String userName;
    private String userPicture;
    private Boolean hasLoggedInWithPassword;
    private HashMap<String, Object> dateJoined = null;

    public User() {

    }

    public User(String email, String userName, String userPicture, Boolean hasLoggedInWithPassword, HashMap<String, Object> dateJoined) {
        this.email = email;
        this.userName = userName;
        this.userPicture = userPicture;
        this.hasLoggedInWithPassword = hasLoggedInWithPassword;
        this.dateJoined = dateJoined;
    }

    protected User(Parcel in) {
        email = in.readString();
        userName = in.readString();
        userPicture = in.readString();

        int size = in.readInt();
        for (int i = 0; i < size; i++) {
            String key = in.readString();
            Object value = in.readString();
            dateJoined.put(key, value);
        }
    }

    public static final Creator<User> CREATOR = new Creator<User>() {
        @Override
        public User createFromParcel(Parcel in) {
            return new User(in);
        }

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

    public String getEmail() {
        return email;
    }

    public String getUserName() {
        return userName;
    }

    public String getUserPicture() {
        return userPicture;
    }

    public Boolean getHasLoggedInWithPassword() {
        return hasLoggedInWithPassword;
    }

    public HashMap<String, Object> getDateJoined() {
        return dateJoined;
    }

    @Override
    public int describeContents() {
        Log.i("describeUser", "describe content from User.java");

        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {

        Log.i("write to Parcel", "write to Parcel from User.java");
        dest.writeString(email);
        dest.writeString(userName);
        dest.writeString(userPicture);
        dest.writeInt(hasLoggedInWithPassword ? 1:0);

        dest.writeInt(dateJoined.size());
        for (HashMap.Entry<String, Object> entry : dateJoined.entrySet()) {
            dest.writeString(entry.getKey());
            dest.writeString(String.valueOf(entry.getValue()));
        }
    }
}

I'm stuck in these methods in the EventDetails class:

protected EventDetails(Parcel in) {
    id = in.readString();
    eventName = in.readString();
    eventUnixTime = in.readLong();

    final int size = in.readInt();
    for (int i = 0; i < size; i++) {
        String key = in.readString();
        User user = in.readHashMap(userMap);
        pickedFriendsHashMap.put(key, user);
    }
}

 @Override
    public void writeToParcel(Parcel dest, int flags) {

        dest.writeInt(pickedFriendsHashMap.size());

        for (HashMap.Entry<String, User> entry :    pickedFriendsHashMap.entrySet()) {
            dest.writeString(entry.getKey());

        dest.writeInt(listLength);

        for (User user: userList) {
            dest.writeParcelable(user, 0);
        }
    }

    dest.writeString(id);
    dest.writeString(eventName);
    dest.writeLong(eventUnixTime);
}

Please advise how I can properly put these classes in parcels and send in bundle.

Thank you.

-R

Community
  • 1
  • 1
runrmrf
  • 71
  • 2
  • 6

1 Answers1

0

Android studio already provide plugin (Android Parcelable code generator) to generate Parcelable methods automatically.

For using above plugin i have create below classes with Parcelable auto generated methods

public class EventDetails implements Parcelable {

    private String id;
    private String eventName;
    private Long eventUnixTime;
    private HashMap<String, User> pickedUser;


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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(this.id);
        dest.writeString(this.eventName);
        dest.writeValue(this.eventUnixTime);
        dest.writeSerializable(this.pickedUser);
    }

    public EventDetails() {
    }

    protected EventDetails(Parcel in) {
        this.id = in.readString();
        this.eventName = in.readString();
        this.eventUnixTime = (Long) in.readValue(Long.class.getClassLoader());
        this.pickedUser = (HashMap<String, User>) in.readSerializable();
    }

    public static final Creator<EventDetails> CREATOR = new Creator<EventDetails>() {
        @Override
        public EventDetails createFromParcel(Parcel source) {
            return new EventDetails(source);
        }

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

public class User implements Parcelable {
    private String email;
    private String userName;
    private String userPicture;
    private Boolean hasLoggedInWithPassword;
    private HashMap<String, Object> dateJoined = null;

    public User(String email, String userName, String userPicture, Boolean hasLoggedInWithPassword, HashMap<String, Object> dateJoined) {
        this.email = email;
        this.userName = userName;
        this.userPicture = userPicture;
        this.hasLoggedInWithPassword = hasLoggedInWithPassword;
        this.dateJoined = dateJoined;
    }


    public String getEmail() {
        return email;
    }

    public String getUserName() {
        return userName;
    }

    public String getUserPicture() {
        return userPicture;
    }

    public Boolean getHasLoggedInWithPassword() {
        return hasLoggedInWithPassword;
    }

    public HashMap<String, Object> getDateJoined() {
        return dateJoined;
    }


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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(this.email);
        dest.writeString(this.userName);
        dest.writeString(this.userPicture);
        dest.writeValue(this.hasLoggedInWithPassword);
        dest.writeSerializable(this.dateJoined);
    }

    protected User(Parcel in) {
        this.email = in.readString();
        this.userName = in.readString();
        this.userPicture = in.readString();
        this.hasLoggedInWithPassword = (Boolean) in.readValue(Boolean.class.getClassLoader());
        this.dateJoined = (HashMap<String, Object>) in.readSerializable();
    }

    public static final Creator<User> CREATOR = new Creator<User>() {
        @Override
        public User createFromParcel(Parcel source) {
            return new User(source);
        }

        @Override
        public User[] newArray(int size) {
            return new User[size];
        }
    };
}
Haresh Chhelana
  • 24,720
  • 5
  • 57
  • 67
  • 4
    This is incorrect and it will throw a `java.io.NotSerializableException` when marshalling. Your User class does not implement Serializable. You cannot expect to write a serializable if part of the object is not Serializable (i.e. `User`). Also, you cannot simply have `User` implement `Serializable` and expect it to work. You will either need to use a different data structure (e.g. a `List`) or you will need to handle reading/writing from/to a Parcel on your own. – w3bshark Dec 20 '17 at 17:43
  • 1
    Incorrect. Link to Parcelable - https://developer.android.com/reference/android/os/Parcel.html#writeSerializable(java.io.Serializable) Excerpt from the Documentation - It is strongly recommended that this method be avoided, since the serialization overhead is extremely large, and this approach will be much slower than using the other approaches to writing data in to a Parcel. – Ahmed Apr 03 '18 at 03:49