Android for循环没有明显原因提前破解

时间:2017-03-18 05:53:45

标签: java android

我有一个(无可否认的非常大)for循环,它会提前结束。它首先通过递归方法将所有歌曲定位在用户的音乐文件夹中,然后将它们添加到数据库中以便将来更快地检索。我把它设置在ASync上,相关部分在下面。

private void updateSongsDB() {
    ArrayList<File> fileList = getAllDirectories(mCurrentRootFile);
    int numDirectories = fileList.size();
    int numScanned = 0;
    resetDB();

    // Setup the strings
    String title;
    String artist;
    String album;
    String duration;
    String genre;
    String track_number;
    String total_tracks;

    try{
        for(File file : fileList) {
            try {
                MediaMetadataRetriever mMetaDataRetriever = new MediaMetadataRetriever();
                mMetaDataRetriever.setDataSource(file.getAbsolutePath());

                if (mMetaDataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_HAS_AUDIO) != null) {
                    // Extract the information
                    title = mMetaDataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE);
                    title = (title != null) ? title : "";

                    artist = mMetaDataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST);
                    artist = (artist != null) ? artist : "";

                    album = mMetaDataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM);
                    album = (album != null) ? album : "";

                    duration = mMetaDataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
                    duration = (duration != null) ? duration : "";

                    genre = mMetaDataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_GENRE);
                    genre = (genre != null) ? genre : "";

                    track_number = mMetaDataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_CD_TRACK_NUMBER);
                    track_number = (track_number != null) ? track_number : "";

                    total_tracks = mMetaDataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS);
                    total_tracks = (total_tracks != null) ? total_tracks : "";

                    insertDBRow(title, artist, album, duration, genre, track_number, total_tracks, file.getAbsolutePath());
                }
            }
            catch (IllegalArgumentException e) {
                // This is not a playable media file, ignore it
            }
            numScanned++;
            publishProgress((float) ((numScanned / (float) numDirectories) * 100));

            // Escape early if cancel() is called
            //if (isCancelled()) break;
        }
    }
    catch(Exception e) {
        // No files in the list
    }
    Log.d("Total Files", String.valueOf(numDirectories));
    Log.d("Number Scanned", String.valueOf(numScanned));
}

private void resetDB() {
    mSongListDB.execSQL(SongReaderContract.SQL_DELETE_ENTRIES);
    mSongListDB.execSQL(SongReaderContract.SQL_CREATE_ENTRIES);
}

private ArrayList<File> getAllDirectories(File rootFile) {
    File[] fileList = rootFile.listFiles();

    ArrayList<File> dirs = new ArrayList<>();

    try {
        for (File file : fileList) {
            if (file.isDirectory()) {
                dirs.addAll(getAllDirectories(file));
            } else {
                dirs.add(file);
            }
        }
    }
    catch(Exception e) {
        // No files in the list
    }

    return dirs;
}

private void insertDBRow(String title, String artist, String album, String duration,
                         String genre, String track_number, String total_tracks, String path) {

    ContentValues values = new ContentValues();

    values.put(SongReaderContract.FeedEntry.COLUMN_NAME_TITLE, title);
    values.put(SongReaderContract.FeedEntry.COLUMN_NAME_ARTIST, artist);
    values.put(SongReaderContract.FeedEntry.COLUMN_NAME_ALBUM, album);
    values.put(SongReaderContract.FeedEntry.COLUMN_NAME_DURATION, duration);
    values.put(SongReaderContract.FeedEntry.COLUMN_NAME_GENRE, genre);
    values.put(SongReaderContract.FeedEntry.COLUMN_NAME_TRACK_NUMBER, track_number);
    values.put(SongReaderContract.FeedEntry.COLUMN_NAME_TOTAL_TRACKS, total_tracks);
    values.put(SongReaderContract.FeedEntry.COLUMN_NAME_PATH, path);

    // Insert the new row
    mSongListDB.insert(SongReaderContract.FeedEntry.TABLE_NAME, null, values);
}

在我的测试设备上,我有1774首歌曲。正好填充了fileList,因为我的LogCat显示了1774个文件。但是,无论我做什么,for循环总是在978或979次迭代时停止,如下面的日志中所示。

03-17 22:36:40.011 10927-11112/com.demo41357.simplemusicplayer D/mali_winsys: new_window_surface returns 0x3000,  [1440x2560]-format:1
03-17 22:36:40.161 10927-10927/com.demo41357.simplemusicplayer W/art: Before Android 4.1, method int android.support.v7.widget.ListViewCompat.lookForSelectablePosition(int, boolean) would have incorrectly overridden the package-private method in android.widget.ListView
03-17 22:36:40.161 10927-10927/com.demo41357.simplemusicplayer I/InjectionManager: dispatchCreateOptionsMenu :com.demo41357.simplemusicplayer.MainActivity
03-17 22:36:40.161 10927-10927/com.demo41357.simplemusicplayer I/InjectionManager: dispatchPrepareOptionsMenu :com.demo41357.simplemusicplayer.MainActivity
03-17 22:36:40.231 10927-10927/com.demo41357.simplemusicplayer D/ViewRootImpl: #1 mView = android.widget.LinearLayout{b83ac55 V.E...... ......I. 0,0-0,0}
03-17 22:36:40.241 10927-10927/com.demo41357.simplemusicplayer D/ViewRootImpl: MSG_RESIZED_REPORT: ci=Rect(0, 96 - 0, 0) vi=Rect(0, 96 - 0, 0) or=1
03-17 22:36:40.301 10927-11112/com.demo41357.simplemusicplayer D/mali_winsys: new_window_surface returns 0x3000,  [296x176]-format:1
03-17 22:36:40.311 10927-10927/com.demo41357.simplemusicplayer D/ViewRootImpl: MSG_RESIZED_REPORT: ci=Rect(0, 0 - 0, 0) vi=Rect(0, 0 - 0, 0) or=1
03-17 22:36:40.311 10927-10927/com.demo41357.simplemusicplayer I/Timeline: Timeline: Activity_idle id: android.os.BinderProxy@3878aec time:88802249
03-17 22:36:41.831 10927-10927/com.demo41357.simplemusicplayer D/ViewRootImpl: #3 mView = null
03-17 22:36:41.841 10927-10927/com.demo41357.simplemusicplayer D/ViewRootImpl: #1 mView = android.widget.LinearLayout{cce9e37 V.E...... ......I. 0,0-0,0}
03-17 22:36:41.891 10927-11112/com.demo41357.simplemusicplayer D/mali_winsys: new_window_surface returns 0x3000,  [296x176]-format:1
03-17 22:36:41.901 10927-10927/com.demo41357.simplemusicplayer D/ViewRootImpl: MSG_RESIZED_REPORT: ci=Rect(0, 0 - 0, 0) vi=Rect(0, 0 - 0, 0) or=1
03-17 22:36:43.841 10927-10927/com.demo41357.simplemusicplayer D/ViewRootImpl: #3 mView = null
03-17 22:36:45.321 10927-10927/com.demo41357.simplemusicplayer D/ViewRootImpl: ViewPostImeInputStage processPointer 0
03-17 22:36:45.421 10927-10927/com.demo41357.simplemusicplayer D/ViewRootImpl: ViewPostImeInputStage processPointer 1
03-17 22:36:45.441 10927-10927/com.demo41357.simplemusicplayer I/InjectionManager: dispatchPrepareOptionsMenu :com.demo41357.simplemusicplayer.MainActivity
03-17 22:36:45.471 10927-10927/com.demo41357.simplemusicplayer I/ListPopupWindow: Could not find method setEpicenterBounds(Rect) on PopupWindow. Oh well.
03-17 22:36:45.521 10927-10927/com.demo41357.simplemusicplayer D/AbsListView: Get MotionRecognitionManager
03-17 22:36:45.521 10927-10927/com.demo41357.simplemusicplayer E/MotionRecognitionManager: mSContextService = android.hardware.scontext.ISContextService$Stub$Proxy@bcd8327
03-17 22:36:45.521 10927-10927/com.demo41357.simplemusicplayer E/MotionRecognitionManager: motionService = com.samsung.android.motion.IMotionRecognitionService$Stub$Proxy@ba0e9d4
03-17 22:36:45.521 10927-10927/com.demo41357.simplemusicplayer E/MotionRecognitionManager: motionService = com.samsung.android.motion.IMotionRecognitionService$Stub$Proxy@ba0e9d4
03-17 22:36:45.531 10927-10927/com.demo41357.simplemusicplayer D/ViewRootImpl: #1 mView = android.widget.PopupWindow$PopupDecorView{5ad8672 V.E...... ......I. 0,0-0,0}
03-17 22:36:45.561 10927-11112/com.demo41357.simplemusicplayer D/mali_winsys: new_window_surface returns 0x3000,  [1040x640]-format:1
03-17 22:36:45.651 10927-10927/com.demo41357.simplemusicplayer D/ViewRootImpl: MSG_RESIZED_REPORT: ci=Rect(0, 0 - 0, 0) vi=Rect(0, 0 - 0, 0) or=1
03-17 22:36:46.641 10927-10927/com.demo41357.simplemusicplayer D/ViewRootImpl: ViewPostImeInputStage processPointer 0
03-17 22:36:46.711 10927-10927/com.demo41357.simplemusicplayer D/ViewRootImpl: ViewPostImeInputStage processPointer 1
03-17 22:36:46.781 10927-10927/com.demo41357.simplemusicplayer I/InjectionManager: dispatchOptionsItemSelected :com.demo41357.simplemusicplayer.MainActivity
03-17 22:36:47.181 10927-11112/com.demo41357.simplemusicplayer D/OpenGLRenderer: endAllActiveAnimators on 0x7f6e5ee800 (MenuPopupWindow$MenuDropDownListView) with handle 0x7f85e78c20
03-17 22:36:47.181 10927-10927/com.demo41357.simplemusicplayer D/ViewRootImpl: #3 mView = null
03-17 22:36:59.311 10927-11976/com.demo41357.simplemusicplayer D/Total Files: 1774
03-17 22:36:59.311 10927-11976/com.demo41357.simplemusicplayer D/Number Scanned: 978
03-17 22:36:59.311 10927-10927/com.demo41357.simplemusicplayer D/POPUP_DISMISSAL: The post execute script ran

从我的ASync的onPostExecute函数调用POPUP_DISMISSAL日志。我检查了它是否是一个内存问题,但运行内存从未超过13MB的20MB可用,CPU使用率从未超过10%。我完全失去了。我已经尝试将for循环重新格式化为:

for (int curFile=0; curFile<numDirectories; curFile++)

但该代码也返回完全相同的978或979条目。我还尝试将整个for循环传递给一个单独的ArrayList,而不是直接插入,然后循环遍历该列表以插入,但第一个for循环仍然只将978或979个项目放入该ArrayList。我想我可以将它拆分成单独的for循环,每个循环只处理500次迭代,但这看起来很混乱和糟糕的练习,以及我甚至不知道它是否会起作用。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

原来我在我的MediaMetaData对象中捕获了错误的异常,所以当它到达一个没有正确初始化的文件时,它会将一个RunTime Exception抛出到我的循环中,结束循环本身。