【问题标题】:Music player app crashes attempting to crawl subfolders looking for audio files音乐播放器应用程序在尝试抓取子文件夹以查找音频文件时崩溃
【发布时间】:2016-02-18 01:04:21
【问题描述】:

我有一个可以运行的音乐播放器应用,但到目前为止,该应用仅设置为在用户指定的顶级文件夹中查找音频文件。我还想查看至少 1 级深度的音频文件的子文件夹。

我的代码尝试在子文件夹中查找音频文件:

//search subfolders of root media directory for audio files
            File[] someFiles = home.listFiles();
            for (int i = 0; i < someFiles.length; i++) {
                File selectedFile = someFiles[i];
                if (selectedFile.isDirectory()) {
                    searchForAudioFiles(selectedFile, uniqueSongIDInt);
                }
            }

不幸的是,我收到了一个空指针异常。我运行调试器试图找出什么变量为空,但还没有弄清楚。

Logcat: java.lang.RuntimeException:无法启动活动 ComponentInfo{com.joshbgold.simplemusicplayer/com.joshbgold.simplemusicplayer.MainActivity}:java.lang.NullPointerException 在 android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2262) 在 android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2316) 在 android.app.ActivityThread.access$700(ActivityThread.java:158) 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:1296) 在 android.os.Handler.dispatchMessage(Handler.java:99) 在 android.os.Looper.loop(Looper.java:176) 在 android.app.ActivityThread.main(ActivityThread.java:5365) 在 java.lang.reflect.Method.invokeNative(Native Method) 在 java.lang.reflect.Method.invoke(Method.java:511) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869) 在 dalvik.system.NativeStart.main(本机方法) 引起:java.lang.NullPointerException 在 com.joshbgold.simplemusicplayer.SongsManager.searchForAudioFiles(SongsManager.java:66) 在 com.joshbgold.simplemusicplayer.SongsManager.getPlayList(SongsManager.java:56) 在 com.joshbgold.simplemusicplayer.MainActivity.onCreate(MainActivity.java:126)

这是第 66 行,Logcat 似乎表明可能导致异常:

   if ((home.listFiles(new FileExtensionFilter()).length > 0)) {

这是完整的 SongsManager 类:

import android.content.Context;
import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;

public class SongsManager {

    public HashMap<String, String> song;
    public String songTitle;
    private String uniqueSongIDString = "0";
    public Context mContext;
    protected String lowerCaseName = "";

    // SDCard Path
    public String MEDIA_PATH = "/storage";
    private ArrayList<HashMap<String, String>> songsList = new ArrayList<>();
    private ArrayList<HashMap<String, String>> filteredSongsList = new ArrayList<>();


    public SongsManager(Context context, String folderPath) {
        mContext = context;
        if (folderPath != null && !"".equals(folderPath)) {
            MEDIA_PATH = folderPath;
        }
    }

    /**
     * Function to read all mp3 files from sdcard
     * and store the details in ArrayList
     */
    public ArrayList<HashMap<String, String>> getPlayList() {

        File home = new File(MEDIA_PATH);

        uniqueSongIDString = "0";
        int uniqueSongIDInt = 0;

        if (songsList != null) {
            songsList.clear();
        }

        if (home.listFiles() != null) {
            //search audio files in root media directory user has selected
            //searchForAudioFiles(home, uniqueSongIDInt);

            //search subfolders of root media directory for audio files
            File[] someFiles = home.listFiles();
            for (int i = 0; i < someFiles.length; i++) {
                File selectedFile = someFiles[i];
                if (selectedFile.isDirectory()) {
                    searchForAudioFiles(selectedFile, uniqueSongIDInt);
                }
            }

        }
        // return songs playlist_item array
        return songsList;
    }

    private void searchForAudioFiles(File home, int uniqueSongIDInt) {
        if ((home.listFiles(new FileExtensionFilter()).length > 0)) {
            for (File file : home.listFiles(new FileExtensionFilter())) {  //for each file that is an audio file in home directory
                song = new HashMap<>();  //make a hashmap data structure to store song info

                songTitle = file.getName();

                //remove track numbers from song titles
                songTitle = songTitle.replaceFirst("^\\d*\\s", "");  //replaces leading digits & following space
                songTitle = songTitle.replaceFirst("^\\d*\\-\\d*", "");  //replaces leading digits, following hyphen, and following digits

                song.put("songTitle", songTitle);
                song.put("songPath", file.getPath());
                song.put("songUniqueID", uniqueSongIDString);
                uniqueSongIDInt++;
                uniqueSongIDString = String.valueOf(uniqueSongIDInt);

                // Adding each song to SongList
                songsList.add(song);
            }
        }
    }

    /**
     * Class to filter files which are having .mp3 extension
     */
    class FileExtensionFilter implements FilenameFilter {
        public boolean accept(File dir, String name) {
            lowerCaseName = name.toLowerCase();
            return (name.endsWith(".mp3") || name.endsWith(".wma") || name.endsWith(".wav") || name.endsWith(".m4a") || name.endsWith(".flac"));
        }
    }

    // Filter Class
    public ArrayList<HashMap<String, String>> filter(String searchString) {
        searchString = searchString.toLowerCase(Locale.getDefault());

        songsList.clear();
        songsList = getPlayList();

        //searchString is empty, so show all songs in results
        if (searchString.length() == 0) {

            if (filteredSongsList != null) {
                filteredSongsList.clear();
            }
            filteredSongsList = songsList;
        }

        //only return songs that match the search string
        else {

            if (filteredSongsList != null) {
                filteredSongsList.clear();
            }

            for (HashMap<String, String> song : songsList) {
                if (song != null) {
                    String songTitle = song.get("songTitle");
                    if (songTitle.toLowerCase().contains(searchString)) {
                        filteredSongsList.add(song);
                    }
                }
            }
        }

        return filteredSongsList;
    }
}

你可以从 Github hereclone 整个项目

【问题讨论】:

    标签: android


    【解决方案1】:

    listFiles() 的 javadoc 清楚地表明它可以在目录为空时返回 null。所以你应该检查并处理这种情况。

    【讨论】:

    • 我想你已经找到了解决办法。我现在正在测试这个。我确实在代码的前面检查了 listFiles() 是否为 null,但是当我稍后在代码中调用 listFiles 方法时,我没有检查 null!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-13
    • 2020-01-26
    相关资源
    最近更新 更多