Как реализовать parcelable с моим настраиваемым классом, содержащим Hashmap и SparseArray?

Мне нужно реализовать parcelable в моем пользовательском классе "ArtistInfo" со следующей структурой:

    public class ArtistInfo implements Parcelable {

    private String artist;

    // album name to list of ids of songs
    private HashMap> albumInfo;

    // song id to songInfo
    private SparseArray songsMap;

    protected ArtistInfo(Parcel in) {
        artist = in.readString();
    }

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

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

    public String getArtist() {
        return artist;
    }

    public void setArtist(String artist) {
        this.artist = artist;
    }

    public void addSongsInfoToAlbum(List songsInfo, String album) {
        if (albumInfo == null) {
            albumInfo = new HashMap();
        }

        if (songsMap == null) {
            songsMap = new SparseArray();
        }
        List songsIds = new ArrayList();
        for (SongInfo songInfo : songsInfo) {
            songsIds.add(songInfo.getId());
            songsMap.put(songInfo.getId(), songInfo);
        }
        List songsIdsForAlbum = getSongIdsForAlbum(album);
        songsIdsForAlbum.addAll(songsIds);
        albumInfo.put(album, songsIdsForAlbum);
    }

    private List getSongIdsForAlbum(String album) {
        if (albumInfo == null) {
            return new ArrayList();
        }

        List songsIds = albumInfo.get(album);
        return songsIds == null ? new ArrayList() : songsIds;
    }

    public HashMap> getAlbumInfo() {
        return albumInfo;
    }

    public SparseArray getSongsMap() {
        if (songsMap == null) {
            songsMap = new SparseArray();
        }
        return songsMap;
    }

    @Override
    public String toString() {
        return "ArtistInfo{" +
                "artist='" + artist + '\'' +
                ", albumInfo = " + albumInfo.toString() +
                ", songsMap = " + songsMap.toString() +
                '}';
    }

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(artist);
    }
}

А ниже представлена ​​структура класса SongInfo, используемого в указанном выше классе:

public class SongInfo implements Parcelable {

    private Integer id;

    private String name;

    private String url;

    public SongInfo(Integer id, String name, String url) {
        this.id = id;
        this.name = name;
        this.url = url;
    }

    protected SongInfo(Parcel in) {
        if (in.readByte() == 0) {
            id = null;
        } else {
            id = in.readInt();
        }
        name = in.readString();
        url = in.readString();
    }

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

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

    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 String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        if (id == null) {
            dest.writeByte((byte) 0);
        } else {
            dest.writeByte((byte) 1);
            dest.writeInt(id);
        }
        dest.writeString(name);
        dest.writeString(url);
    }
}

Теперь, как вы можете видеть, нет проблем с реализацией интерфейса Parcelable в классе SongInfo, но я не могу понять, как читать и записывать переменные albumInfo и песниКарта в методе Constructor и writeToParcel соответственно. Может кто-нибудь, пожалуйста, помогите мне понять, как мне это сделать. Спасибо!

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
231
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Идея состоит в том, чтобы перебрать каждый элемент в albumInfo и songsMap, а затем добавить его в Parcelable.

Пишите в посылку.

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(artist);

    // Write album info
    dest.writeInt(albumInfo.size());
    for (Map.Entry<String, List<Integer>> item : albumInfo.entrySet()) {
        dest.writeString(item.getKey());
        dest.writeList(item.getValue());
    }

    // Write song map
    dest.writeInt(songsMap.size());
    for (int i = 0; i < songsMap.size(); i++) {
        int key = songsMap.keyAt(i);
        dest.writeInt(key);
        dest.writeParcelable(songsMap.get(key), flags);
    }
}

Читать из посылки

protected ArtistInfo(Parcel in) {
    artist = in.readString();

    // Read album info
    albumInfo = new HashMap<>();
    int albumInfoSize = in.readInt();
    for (int i = 0; i < albumInfoSize; i++) {
        String key = in.readString();
        List<Integer> value = new ArrayList<>();
        in.readList(value, null);
        albumInfo.put(key, value);
    }

    // Read song map
    songsMap = new SparseArray<>();
    int songsMapSize = in.readInt();
    for (int i = 0; i < songsMapSize; i++) {
        int key = in.readInt();
        SongInfo value = in.readParcelable(SongInfo.class.getClassLoader());
        songsMap.put(key, value);
    }
}

Это сработало. Спасибо! Не могли бы вы объяснить значение флагов в функции writeToParcel, потому что я не понимал, как это работает.

tom 16.09.2018 12:51

@tom на самом деле мне не нужен этот флаг, поэтому я просто передаю флаги, которые передаются методу writeToParcel. Вы можете увидеть эту ссылку, чтобы найти свой ответ stackoverflow.com/questions/44203223/…

Son Truong 16.09.2018 13:14

Другие вопросы по теме