如何使用包含Hashmap和SparseArray的自定义类实现可包裹性?

时间:2018-09-16 09:33:31

标签: java android parcelable

我需要在我的自定义类“ ArtistInfo”中实现parcelable  具有以下结构:

    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);
    }
}

现在,您可以看到在SongInfo类中实现Parcelable接口没有问题,但是我无法理解如何读写 albumInfo songsMap 分别在Constructor和writeToParcel方法中的变量。有人可以帮我了解我应该如何进行。谢谢!

1 个答案:

答案 0 :(得分:0)

这个想法是遍历albumInfosongsMap中的每个项目,然后将其添加到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);
    }
}