Android Java -传递对象列表(内存浪费)



我有一个巨大的listSong对象。每个对象持有4个Strings(标题、专辑、艺术家、路径)和一个integer(稍后获取专辑封面的album_id)。然而,我需要将这个列表的一部分甚至整个list传递给一个新的activity,它将播放这些歌曲。

但是是的,你是对的!这是很大的内存!我通过仅传递路径来减少它,并且在新活动的onCreate()方法中,我将读取设备上的所有歌曲,并仅在路径匹配时将它们添加到播放列表中。这仍然需要时间和可能比应该占用更多的内存。

我能做些什么来减少内存使用和时间,以获得歌曲的list从一个活动到另一个?

如果将路径列表传递给新活动并通过其路径读取文件(直接)的方法是一个好主意,我如何做到这一点?到目前为止,我有这个代码,但它是低效的。它将播放列表中文件的路径列表作为参数,并读取外部存储上的所有歌曲。然后它会检查每首歌的路径是否在路径列表中,如果不在则继续。

public static List<Song> getSongList(List<String> pathList, Context c) {
    Cursor audioCursor = c.getContentResolver().query(
            MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
            new String[] { "*" }, null, null, Media.TITLE + " ASC");
    ArrayList<Song> songsList = new ArrayList<Song>();
    if (audioCursor != null) {
        if (audioCursor.moveToFirst()) {
            do {
                String path = audioCursor.getString(audioCursor
                        .getColumnIndex(MediaStore.Audio.Media.DATA));

                if( !pathList.contains(path) ){
                    //if it's not in the list, we don't want it!
                    continue;
                }
                String title = audioCursor.getString(audioCursor
                        .getColumnIndex(MediaStore.Audio.Media.TITLE));
                String album = audioCursor.getString(audioCursor
                        .getColumnIndex(MediaStore.Audio.Media.ALBUM));
                String artist = audioCursor.getString(audioCursor
                        .getColumnIndex(MediaStore.Audio.Media.ARTIST));
                int album_id = audioCursor.getInt(audioCursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
                Song s = new Song();
                s.setPath(path);
                s.setTitle(title);
                s.setArtist(artist);
                s.setAlbum(album);
                s.setAlbumId(album_id);
                songsList.add(s);
            } while (audioCursor.moveToNext());
        }
    }
    // return songs list array
    return songsList;
}

您是否考虑过使用静态变量来保存列表的类?可以从全局所有活动访问的东西?

比如

public class MYClass
{
public static ArrayList<Song> Songs;
public MYClass()
{
//Load here
}


}
你可以(可选)使用SingleTon模式来防止不必要的错误。

我要做的是提供一个singleton,它可以在您的应用程序中的任何地方访问,并且只有一个数据实例存在。这是通过private构造函数和public static get(...)方法实现的,如下所示…

public class SongStore {
    private static SongStore sSongStore;
    private Context mContext;
    private ArrayList<Song> mSongList;
    private SongStore(Context context) {
        mContext = context;
        loadData();
    }
    public static SongStore get(Context context) {
        if (sSongStore == null) {
            sSongStore = new SongStore(context.getApplicationContext());
        }
        return sSongStore;
    }
    private void loadData() {
        // load the data
    }
    public ArrayList<Song> getSongs() { ... }
}

无论您在哪个活动中,您只需执行-> SongStore .get(YourClass.this).getSongs();即可获得Song s。

您可以从ContentProvider访问歌曲,因此不需要在Activities之间传递它们。

你所要做的就是在onStop()中释放歌曲的Array,所以当活动在后台时它不会占用内存。

我的意思是:

public void onStop(){
   this.songsList = null;
}

另外,如果你真的想把这些歌曲从一个Activity传递到另一个Activity(在Intent中),这个解决方案也会在这种情况下释放歌曲。

时间注意事项:

如果生成ArrayList of Songs真的需要很长时间,那么你可以使用其他人已经建议的Singleton概念来缓存它。但是您应该注意静态引用,以避免内存泄漏。

最新更新