我有一个巨大的list
的Song
对象。每个对象持有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
,它可以在您的应用程序中的任何地方访问,并且只有一个数据实例存在。这是通过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概念来缓存它。但是您应该注意静态引用,以避免内存泄漏。