从SharedPreferences中获取Parcelable对象会产生巨大的内部ArrayList

时间:2014-11-25 13:51:16

标签: java android arraylist sharedpreferences gson

我有两个对象,播放列表和歌曲。 我使用SharedPreferences来存储和获取播放列表对象。 播放列表对象具有Song对象的ArrayList。 播放列表和歌曲都是可以分配的。

当我想获得存储的播放列表时,我会得到一个巨大的ArrayList<Song>。 看起来好像它已经被多年的几次传播所累积。

public void savePlaylist(Playlist playlist) {
    Gson gson = new GsonBuilder().create();
    int fileIndex = playlist.getFileIndex();
    if (fileIndex == -1) {
        fileIndex = getPlaylistCount();
        fileIndex++;
        playlist.setFileIndex(fileIndex);           
    }   
    putString(fileIndex+"", gson.toJson(playlist));
    putInt(PLAYLIST_COUNT, fileIndex);
}
public Playlist getPlaylist(int index) {
    String key = index + "";
    Playlist savedPlaylist;
    Gson gson = new GsonBuilder().create();
    String savedValue = preferences.getString(key, "");
    if (savedValue.equals("")) {
        savedPlaylist = null;
    } else {
        savedPlaylist = gson.fromJson(savedValue, Playlist.class);
    }
    return savedPlaylist;
}
public ArrayList<Playlist> getAllPlaylist() {
    int count = getPlaylistCount();
    if (count == 0) {
        return null;
    }
    ArrayList<Playlist> list = new ArrayList<Playlist>();
    for (int i = 1; i <= count; i++) {
        Playlist pl = getPlaylist(i);
        if (pl != null) {
            list.add(pl);
        }
    }
    if (list.size() == 0) {
        return null;
    }
    return list;
}
private int getPlaylistCount() {
    return preferences.getInt(PLAYLIST_COUNT, 0);
}

修改 添加了对象类

Song.java

public class Song implements Parcelable{

private long id;
private String title;
private String artist;
private String path;
private String size;
private String extension;
private int year;
private long albumId;
private long duration;
private String artUrl;

private boolean selected = false;
private boolean checked = false;

public Song(long id, String title, String artist, String path, String size, long duration, 
        String extension, int year, long albumId) {
    super();
    this.id = id;
    this.title = title;
    this.artist = artist;
    this.path = path;
    this.size = size;
    this.duration = duration;
    this.extension = extension;
    this.year = year;
    this.albumId = albumId;
}

public Song(long id, String title, String artist, String path, long duration, 
        int year, long albumId, String artUrl) {
    super();
    this.id = id;
    this.title = title;
    this.artist = artist;
    this.path = path;
    this.duration = duration;
    this.year = year;
    this.albumId = albumId;
    this.artUrl = artUrl;
}

public Song(long id, String title, String artist, int year, long albumId,
        long duration) {
    super();
    this.id = id;
    this.title = title;
    this.artist = artist;
    this.year = year;
    this.albumId = albumId;
    this.duration = duration;
}
public Song(long id, String title, String artist, int year, long albumId,
        long duration, String path) {
    super();
    this.id = id;
    this.title = title;
    this.artist = artist;
    this.year = year;
    this.albumId = albumId;
    this.duration = duration;
    this.path = path;
}

public Song(Parcel in) {
    id = in.readLong();
    title = in.readString();
    artist = in.readString();
    path = in.readString();
    size = in.readString();
    duration = in.readLong();
    extension = in.readString();
    year = in.readInt();
    albumId = in.readLong();
    artUrl = in.readString();
}

public String getYearString() {
    return ""+this.year;
}

private String lazyDurationString;

public String getDurationString() {
    if (lazyDurationString != null) {
        return lazyDurationString;
    }
    lazyDurationString = "";
    int hourInMillis = 1000*60*60;
    if (duration >= hourInMillis) {
        lazyDurationString = String.format(Locale.ENGLISH, "%02d:%02d:%02d",
                TimeUnit.MILLISECONDS.toHours(duration),
                TimeUnit.MILLISECONDS.toMinutes(duration) - 
                TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(duration)),
                TimeUnit.MILLISECONDS.toSeconds(duration) - 
                TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(duration)));
    } else {
        lazyDurationString = String.format(Locale.ENGLISH, "%02d:%02d",
                TimeUnit.MILLISECONDS.toMinutes(duration),
                TimeUnit.MILLISECONDS.toSeconds(duration) - 
                TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(duration)));
    }
    return lazyDurationString;
}

public long getId() {
    return id;
}

public void setId(long id) {
    this.id = id;
}

public String getTitle() {
    return title;
}

public void setTitle(String title) {
    this.title = title;
}

public String getArtist() {
    return artist;
}

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

public int getYear() {
    return year;
}

public void setYear(int year) {
    this.year = year;
}

public long getAlbumId() {
    return albumId;
}

public void setAlbumId(long albumId) {
    this.albumId = albumId;
}

public long getDuration() {
    return duration;
}

public void setDuration(long duration) {
    this.duration = duration;
}

public String getPath() {
    return path;
}

public void setPath(String path) {
    this.path = path;
}

public String getSize() {
    return size;
}

public void setSize(String size) {
    this.size = size;
}

public String getExtension() {
    return extension;
}

public void setExtension(String extension) {
    this.extension = extension;
}

public void setArtUrl(String artUrl) {
    this.artUrl = artUrl;
}

public String getArtUrl() {
    return artUrl;
}

public boolean isSelected() {
    return selected;
}

public void setSelected(boolean selected) {
    this.selected = selected;
}

public boolean isChecked() {
    return checked;
}

public void setChecked(boolean checked) {
    this.checked = checked;
}

public int describeContents() {
    return 0;
}

public void writeToParcel(Parcel dest, int flags) {
    dest.writeLong(id);
    dest.writeString(title);
    dest.writeString(artist);
    dest.writeString(path);
    dest.writeString(extension);
    dest.writeString(size);
    dest.writeLong(duration);
    dest.writeLong(albumId);
    dest.writeInt(year);
    dest.writeString(artUrl);
}

public static final Parcelable.Creator<Song> CREATOR = new Creator<Song>() {

    @Override
    public Song createFromParcel(Parcel in) {
        return new Song(in);
    }

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

};

}

Playlist.java

public class Playlist implements Parcelable{

private String title = "";
private ArrayList<Song> songs;
private int currentIndex = 0;
private int fileIndex = -1;

public Playlist() {
    songs = new ArrayList<Song>();
}

public Playlist(Parcel in) {
    this();
    title = in.readString();
    currentIndex = in.readInt();
    fileIndex = in.readInt();
    in.readTypedList(songs, Song.CREATOR);
}

public String getTotalDuration() {
    if (songs == null) {
        return "Your playlist is empty";
    }
    int totalTime= 0;
    for (Song song : songs) {
        totalTime += song.getDuration();
    }
    String result = "";
    int minutes = (int) TimeUnit.MILLISECONDS.toMinutes(totalTime);
    result = songs.size() + " songs, " + minutes + " min.";
    return result;
}

public void swapSongs(int index1, int index2) {
    Collections.swap(this.songs, index1, index2);

}

public void generateTitle() {
    String date = "";
    SimpleDateFormat df = new SimpleDateFormat("dd/MM/yy", Locale.ENGLISH);
    date = df.format(new Date());
    title = "new playlist(" + date + ")";       
}

public void addSong(Song song) {
    songs.add(song);
}

public enum RemoveResult {
    CurrentSong,
    IndexChanged,
    NoChange,
    LastSong
}

public RemoveResult removeSongAtIndex(int index) {
    if (songs.size() > 0) {
        songs.remove(index);
    }
    if (songs.size() == 0) {
        return RemoveResult.LastSong;
    }
    if (currentIndex > index) {
        currentIndex--;
        return RemoveResult.IndexChanged;
    }
    if (currentIndex == index) {
        if (currentIndex >= songs.size()) {
            currentIndex = 0;
        }
        return RemoveResult.CurrentSong;
    }

    return RemoveResult.NoChange;
}

public Song getSongAtIndex(int index) {
    return songs.get(index);
}

public int indexOfSong(Song song) {
    return songs.indexOf(song);
}

public int getSize() {
    return songs.size();
}

public String getTitle() {
    return title;
}

public void setTitle(String title) {
    this.title = title;
}

public ArrayList<Song> getSongs() {
    return songs;
}

public void setSongs(ArrayList<Song> songs) {
    this.songs = songs;
}

public int getCurrentIndex() {
    return currentIndex;
}

public void setCurrentIndex(int currentIndex) {
    this.currentIndex = currentIndex;
}

public boolean isNotEmpty() {
    return (songs.size() > 0) ? true : false;
}

public void setFileIndex(int fileIndex) {
    this.fileIndex = fileIndex;
}

public int getFileIndex() {
    return fileIndex;
}

public void clearPlaylist() {
    if (songs.size() > 0) {
        songs.clear();
    }
}

@Override
public int describeContents() {
    // TODO Auto-generated method stub
    return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(title);
    dest.writeInt(currentIndex);
    dest.writeInt(fileIndex);
    dest.writeTypedList(songs);
}

public static final Parcelable.Creator<Playlist> CREATOR = new Creator<Playlist>() {

    @Override
    public Playlist createFromParcel(Parcel source) {
        return new Playlist(source);
    }

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

}

1 个答案:

答案 0 :(得分:0)

您确定问题与Gson序列化有关吗?我已经添加了您的代码,并在活动的创建中执行了此操作:

Playlist p = new Playlist();
p.setTitle("Test Playlist");
Song s = new Song(1, "Test Song1", "Me", 2014, 1, 11111);
Song s2 = new Song(2, "Test Song2", "Me", 2014, 1, 11111);
Song s3 = new Song(3, "Test Song3", "Me", 2014, 1, 11111);
p.addSong(s);
p.addSong(s2);
p.addSong(s3);
savePlaylist(p);

Playlist p2 = getPlaylist(1);
Log.i("Playlist:", ""+p2.getSize());

我总是得到:

  

播放列表:3