首页 > 解决方案 > 如何使用包含 Hashmap 和 SparseArray 的自定义类实现 parcelable?

问题描述

我需要在我的自定义类“ArtistInfo”中实现 parcelable,其结构如下:

    公共类 ArtistInfo 实现 Parcelable {

    私人弦乐艺术家;

    //专辑名称到歌曲ID列表
    私有HashMap>专辑信息;

    // 歌曲 ID 到歌曲信息
    私有 SparseArray 歌曲地图;

    受保护的艺术家信息(包裹){
        艺术家 = in.readString();
    }

    public static final Creator CREATOR = new Creator() {
        @覆盖
        public ArtistInfo createFromParcel(包裹在){
            返回新的 ArtistInfo(in);
        }

        @覆盖
        公共 ArtistInfo[] newArray(int size) {
            返回新的 ArtistInfo[大小];
        }
    };

    公共字符串 getArtist() {
        回归艺术家;
    }

    公共无效setArtist(字符串艺术家){
        this.artist = 艺术家;
    }

    public void addSongsInfoToAlbum(列出歌曲信息,字符串专辑){
        if (albumInfo == null) {
            专辑信息 = 新的 HashMap();
        }

        if (songsMap == null) {
            songMap = new SparseArray();
        }
        ListsongIds = new ArrayList();
        对于(歌曲信息歌曲信息:歌曲信息){
            songIds.add(songInfo.getId());
            songMap.put(songInfo.getId(), songInfo);
        }
        ListsongIdsForAlbum = getSongIdsForAlbum(album);
        songIdsForAlbum.addAll(songsIds);
        专辑信息.put(专辑,songsIdsForAlbum);
    }

    私人列表 getSongIdsForAlbum(字符串专辑){
        if (albumInfo == null) {
            返回新的 ArrayList();
        }

        ListsongIds = albumInfo.get(album);
        返回 songIds == null ?新的 ArrayList() : songIds;
    }

    公共HashMap> getAlbumInfo() {
        返回专辑信息;
    }

    公共稀疏数组 getSongsMap() {
        if (songsMap == null) {
            songMap = new SparseArray();
        }
        返回歌曲地图;
    }

    @覆盖
    公共字符串 toString() {
        返回 "艺术家信息{" +
                "艺术家='" + 艺术家 + '\'' +
                ", albumInfo=" + albumInfo.toString() +
                ", songMap=" + songMap.toString() +
                '}';
    }

    @覆盖
    公共 int describeContents() {
        返回0;
    }

    @覆盖
    公共无效writeToParcel(包裹目的地,int标志){
        dest.writeString(艺术家);
    }
}

以下是上述类中使用的“SongInfo”类的结构:

公共类 SongInfo 实现 Parcelable {

    私人整数 id;

    私有字符串名称;

    私人字符串网址;

    public SongInfo(整数 id,字符串名称,字符串 url){
        这个.id = id;
        this.name = 名称;
        这个.url = url;
    }

    受保护的歌曲信息(包裹在){
        if (in.readByte() == 0) {
            身份证=空;
        } 别的 {
            id = in.readInt();
        }
        名称 = in.readString();
        url = in.readString();
    }

    public static final Creator CREATOR = new Creator() {
        @覆盖
        public SongInfo createFromParcel(Parcel in) {
            返回新的 SongInfo(in);
        }

        @覆盖
        公共 SongInfo[] newArray(int size) {
            返回新的 SongInfo[大小];
        }
    };

    公共整数 getId() {
        返回标识;
    }

    公共无效 setId(整数 id){
        这个.id = id;
    }

    公共字符串 getName() {
        返回名称;
    }

    公共无效集合名称(字符串名称){
        this.name = 名称;
    }

    公共字符串 getUrl() {
        返回网址;
    }

    公共无效setUrl(字符串网址){
        这个.url = url;
    }

    @覆盖
    公共 int describeContents() {
        返回0;
    }

    @覆盖
    公共无效writeToParcel(包裹目的地,int标志){
        如果(id == null){
            dest.writeByte((字节) 0);
        } 别的 {
            dest.writeByte((字节) 1);
            dest.writeInt(id);
        }
        dest.writeString(name);
        dest.writeString(url);
    }
}

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

标签: javaandroidparcelable

解决方案


这个想法是遍历每个项目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);
    }
}

推荐阅读