在Android中存储播放列表的正确方法
我正在开发一个能够播放歌曲列表的应用程序。它主要不是音乐播放器,因此不需要多个播放列表。我一直在使用SharedReferences存储用户从其MediaStore中选择的歌曲列表 我已将它们存储在SharedReferences文件中,伪代码如下:在Android中存储播放列表的正确方法,android,architecture,sharedpreferences,Android,Architecture,Sharedpreferences,我正在开发一个能够播放歌曲列表的应用程序。它主要不是音乐播放器,因此不需要多个播放列表。我一直在使用SharedReferences存储用户从其MediaStore中选择的歌曲列表 我已将它们存储在SharedReferences文件中,伪代码如下: Key = "Song"+n Value = _ID 当我需要检索歌曲ID时,我只需循环浏览歌曲+0到歌曲+n的文件 在我需要从列表中删除一首歌曲之前,这一切都很正常。显而易见的解决方案是删除列表中的相关歌曲及其之后的所有歌曲,然后将这些歌曲替换
Key = "Song"+n
Value = _ID
当我需要检索歌曲ID时,我只需循环浏览歌曲+0到歌曲+n的文件
在我需要从列表中删除一首歌曲之前,这一切都很正常。显而易见的解决方案是删除列表中的相关歌曲及其之后的所有歌曲,然后将这些歌曲替换为索引号比以前少1的歌曲
我觉得这件事很糟糕,所以我的问题是:
我所描述的是一种根本不好的存储列表的方法吗?
如果情况不好,有什么更好的选择?
如果以这种方式使用SharedReferences是合理的,那么我删除项目并重新索引列表的想法是一个好主意吗?
如果这不是一个好主意,那么还有什么更好的选择呢?
先谢谢你,安德鲁
我所描述的是一种根本不好的存储列表的方法吗
如果您希望列表包含大量数据,那么这不是存储数据的最佳方式
请注意,SharedReference会在首次加载后缓存,因此加载数据的磁盘访问只需要一次时间。您可以尝试在测试套件的早期加载SharedReference,以避免这种惩罚
另外,在android中解析XML文件和更新数据非常耗时。不建议这样做
如果情况不好,有什么更好的选择
我建议将数据插入SQLite
如果以这种方式使用SharedReference是合理的,那么这就是我的想法
删除项目并重新索引列表是个好主意吗
答案是否定的。原因如上所述
如果这不是一个好主意,那么还有什么更好的办法呢
替代方案
从SQLite检索数据并将其存储在JSON对象中。如果使用XML检索和更新只需几秒钟,而使用JSON检索和更新只需几毫秒
请随时添加/更新答案并提供更多详细信息。有关将JSON数组内容存储到SharedReferences的示例,请参阅。您也可以(而且可能应该)将该JSON数组作为文件存储到设备的文件系统中
public void saveJSONObjectAsFile(String path, JSONObject obj){
File mFile = new File(path);
OutputStream outputStream = null;
try {
outputStream = new FileOutputStream(mFile);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
outputStream.write(obj.toString().getBytes());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
outputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
就个人而言,我不会因为这样一个相对简单的数据支持而与SQLite发生冲突。一个使用SharedReferences从列表中添加/删除歌曲的非常简单的示例该示例假设您的歌曲ID是数字
// SharedPreferences
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor prefsEditor = prefs.edit();
// example song ID selected by user
int selectedSongId = 123;
// example of deleting a song ID...
try {
// get currently stored songs list
JSONArray currentItems = new JSONArray(prefs.getString("songs", new JSONArray().toString()));
// init a new empty songs list
JSONArray updatedItems = new JSONArray();
for (int i = 0; i < currentItems.length(); i++) {
// loop through currently stored list, put each item into new list
// except for the Id user has selected to delete
int songId = currentItems.getInt(i);
if (songId != selectedSongId) {
updatedItems.put(songId);
}
}
// replace old songs list with the new list and save to SharedPreferences
prefsEditor.putString("songs", currentItems.toString()).commit();
} catch (JSONException e) {
e.printStackTrace();
}
// example of adding a song ID to existing songs list
try {
// get currently stored songs list
JSONArray currentItems = new JSONArray(prefs.getString("songs", new JSONArray().toString()));
// add new song Id to list
currentItems.put(selectedSongId);
// save updated songs list back to SharedPreferences
prefsEditor.putString("songs", currentItems.toString()).commit();
} catch (JSONException e) {
e.printStackTrace();
}
有很多更有效的方法可以做到这一点,但这个简化的例子希望能帮助你找到一个好的方向
PS-我输入的示例没有运行它,可能在某个地方出错您的问题不完全清楚。。。您是否将每首歌曲的键/值存储为单独的SharedReferences项?列表中的歌曲不太可能超过50首,您是否仍建议使用JSON?如果是这样,您是否建议将其保存到文件系统中,作为其他海报建议的一个,或将其序列化并保存在SharedReferences中?@user1977132,如果只有50首歌曲,最多100行,则您当前的方法很好。不需要做任何更改。请注意,只有当您看到性能问题时,才需要进行性能调整。如果没有,最好还是保持原样。@Prem假设OP将每首歌曲存储为其自己的共享参考条目,那么这种方法当然不好,即使只存储几十个条目。