当前位置: 首页 > 知识库问答 >
问题:

如何用我的包含Hashmap和Sparsearray的自定义类实现parcelable?

谢典
2023-03-14

我需要用以下结构在我的自定义类“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接口没有问题,但我无法理解如何分别在构造函数和writeToParcel方法中读取和写入AlbumInfoSongSmap变量。有谁能帮我理解一下我该怎么去做那件事。谢谢!

共有1个答案

上官正志
2023-03-14

这个想法是遍历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);
    }
}
 类似资料:
  • 问题内容: 我可以想到以下几个原因,为什么带有整数键的s 比s 要好得多: 的Android文档说:“通常比传统的要慢”。 如果您使用s而不是s 编写代码,那么您的代码将与Map的其他实现一起使用,并且将能够使用所有为Maps设计的Java API。 如果您使用而不是s 编写代码,则您的代码将在非Android项目中运行。 地图会覆盖,而不会覆盖。 但是,每当我尝试在Android项目中使用带有整

  • null 然而,每当我试图在Android项目中使用带有整数键的时,IntelliJ告诉我应该使用。我觉得这真的很难理解。有人知道使用s有什么令人信服的理由吗?

  • 我正在用Visual Studio(2017)构建pybind11项目。安装文件如下: 然后在windows power shell中,我将运行 python设置。皮包 但是它抱怨找不到多个包含文件,我相信它以后也会抱怨缺少库文件: 我知道这个目标在哪里。h是,只是不知道如何将其位置添加到包含路径。 非常感谢你的帮助。

  • 我对Java有很好的理解,但我正在努力学习c来制作游戏,因为我认为c是一种更好的语言。但是我对c有一些问题。 是一个带有字符串构造函数的类,只是在这个类中声明它会导致错误。如果我删除的构造函数,我不会得到错误。 错误:render.cpp:3:16:错误:没有匹配的函数调用着色器::着色器()

  • 本文向大家介绍Java如何实现自定义异常类,包括了Java如何实现自定义异常类的使用技巧和注意事项,需要的朋友参考一下 这篇文章主要介绍了Java如何实现自定义异常类,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 自定义异常类步骤   创建一个类继承异常父类Exception   在具体的实现方法首部抛出异常类(自己创建的那个类),throws的

  • 我需要从包含自动生成的jooq记录的Vaadin网格中添加/删除/自定义列。 现在我喜欢(例如)添加一个按钮。 结果: java.lang.IllegalStateExcture:此Grid的容器不是Grid()构造函数的默认容器 使用Vaadin表,效果很好。但读完这篇文章后,我喜欢使用网格 我在这里找到了发生这种情况的原因 如何使用我在这里找到的简单bean编写容器 我如何才能实现与jooq记