在Android中存储播放列表的正确方法

在Android中存储播放列表的正确方法,android,architecture,sharedpreferences,Android,Architecture,Sharedpreferences,我正在开发一个能够播放歌曲列表的应用程序。它主要不是音乐播放器,因此不需要多个播放列表。我一直在使用SharedReferences存储用户从其MediaStore中选择的歌曲列表 我已将它们存储在SharedReferences文件中,伪代码如下: Key = "Song"+n Value = _ID 当我需要检索歌曲ID时,我只需循环浏览歌曲+0到歌曲+n的文件 在我需要从列表中删除一首歌曲之前,这一切都很正常。显而易见的解决方案是删除列表中的相关歌曲及其之后的所有歌曲,然后将这些歌曲替换

我正在开发一个能够播放歌曲列表的应用程序。它主要不是音乐播放器,因此不需要多个播放列表。我一直在使用SharedReferences存储用户从其MediaStore中选择的歌曲列表

我已将它们存储在SharedReferences文件中,伪代码如下:

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将每首歌曲存储为其自己的共享参考条目,那么这种方法当然不好,即使只存储几十个条目。