2014-11-25 3 views
0

У меня есть два объекта, плейлист и песня. Я использую SharedPreferences для хранения и выбора объектов Playlist. Объекты Playlist имеют объекты ArrayList of Song. Оба плейлиста и песни являются взаимозаменяемыми.Извлечение Parcelable объекта из SharedPreferences дает огромный размер внутреннего ArrayList

Когда я хочу получить сохраненный список воспроизведения, я получаю огромный размер ArrayList<Song>. Кажется, что он умножил свои элементы на hundreads раз.

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

EDIT: классы объектов добавляют

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

} 
+0

Вы должны были бы разместить код от вашего объекта классы. –

+0

Классы, добавленные к сообщению –

+0

SharedPreferences, вероятно, не самый лучший вариант для хранения данных в вашем случае. Рассмотрите возможность использования базы данных SQLite. – Egor

ответ

0

Вы уверены, что проблема связана с сериализацией Gson? Я добавил свой код и сделал это OnCreate о деятельности:

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

Я всегда получаю:

Playlist: 3

+0

Это действительно странно, я очистил данные приложения из настроек Android, и теперь он работает отлично. У меня нет ни малейшего понятия, почему у меня такое странное поведение ... –

+0

Возможно, остались оставшиеся плохие данные из других тестов? :) –

+0

Может быть ... в любом случае, я буду отмечать этот ответ как решенный, так как вы заставили меня понять, что в коде нет ничего плохого, и я должен искать в ... –

Смежные вопросы