Recursively add files in Java - speed issue
First off - I have开发者_Python百科n't had much experience with Java yet, and I'm a beginner when it comes to the Android SDK.
I'm trying to write a music player app, which when started scans the entire SD card for mp3 files.
Currently this is how I'm doing that:
// Recursively add songs in a directory
public void addSongsInDirectory(File dir, String filter) {
File[] files = dir.listFiles();
if (files != null) {
for (File f : files) {
if (f.isDirectory()) {
addSongsInDirectory(f, filter);
} else {
// Create new MimetypesFileTypeMap
MimetypesFileTypeMap mtfm = new MimetypesFileTypeMap();
// Add the mp3 mimetype
mtfm.addMimeTypes("audio/mpeg mp3");
// If current song is audio/mpeg, add it to the list
if (mtfm.getContentType(f).equals(filter)) {
songs.add(f.getName());
}
}
}
}
}
Unfortunately, on my handset with many songs on it, this process takes about 30 seconds. How can I optimize this function so that it works faster (and possibly in the background)?
An Android specific optimisation is to look for a file called .nomedia
in a directory. This is an indication that there are no media files in a directory in any of its subdirectories. The idea is that applications can create a .nomedia
file in their data directories to tell media applications that there's no need to scan them because there's no media in there (or possibly there are media files which are only used internally by the application, such as music from a game).
Alternatively, you could skip writing your own scanner and use the Media Scanner built in to Android. It's simply a matter of querying the appropriate ContentProvider
.
Your code will look something like this:
String[] projection = new String[] {
MediaStore.Audio.Media.ALBUM,
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.TITLE
};
Cursor cursor = managedQuery(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, //URI
projection, //columns to return
null, //rows to return - all
null, //selection arguments - none
null // sort order - default
);
cursor.moveToFirst();
while(! cursor.isLast()) {
Log.d("MediaTest","Found track:");
Log.d("MediaTest","Album " + cursor.getString(0));
Log.d("MediaTest","Artist " + cursor.getString(1));
Log.d("MediaTest","Track " + cursor.getString(2));
cursor.moveToNext();
}
I don't know that this is specific to Android, but this is how I've seen other music players handle this.
The first time your app is used, you let the user know that you have to index his music collection. People expect that this will take a while.
Once you've saved an index file, you can show the index file on start up. While the user is doing other things, you index the music collection in the background. Save the new index file if it's different than the old index file.
Finally, you give the user the option of indexing his music collection anytime he wants. Usually, that's when he knows he's added a new song or two.
You would build the index file using a Java thread spun off of the UI thread.
精彩评论