2017-03-18 35 views
0

我有一個(不可否認非常大)的循環,提前結束。它首先通過遞歸方法在用戶的音樂文件夾中找到所有歌曲,然後將它們添加到數據庫中以便將來更快地檢索。我已經建立了一個ASync,其相關部分如下。Android for循環沒有明顯的原因是提前打破

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: [email protected] 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 = [email protected] 
03-17 22:36:45.521 10927-10927/com.demo41357.simplemusicplayer E/MotionRecognitionManager: motionService = [email protected]ba0e9d4 
03-17 22:36:45.521 10927-10927/com.demo41357.simplemusicplayer E/MotionRecognitionManager: motionService = [email protected]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 

POPUP_DISMISSAL日誌是從我的ASync的onPostExecute函數調用的。我檢查了是否是內存問題,但運行內存從未超過13MB的可用20MB,並且CPU使用率從未超過10%。我完全喪失了。我試過重新格式化for循環來讀取:

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

但該代碼還返回完全相同的978或979條目。我也嘗試將整個for循環傳遞給一個單獨的ArrayList,而不是直接插入,然後遍歷該列表以插入,但第一個for循環仍然只將978或979項放入該ArrayList。我想我可以將它分成單獨的for循環,每個循環只能處理500次迭代,但這看起來很麻煩,實踐也很差,我甚至不知道它是否可行。

任何幫助將不勝感激。

+3

你有兩個空的catch塊。也許你應該在這些方面做點什麼,比如至少打印堆棧跟蹤。 –

+2

首先,我不會把所有的「catch」塊留空。你的代碼默默無聞,你想知道爲什麼... – Dave

+0

嗯,我很笨。謝謝你們,我花了幾個小時看着這個,並沒有注意到我在捕捉錯誤的異常類型,直到你提到它。當setDataSource在MediaMetaDataRetriever上失敗時,它會引發RunTime異常,而不是IllegalArgument異常。這就是您重新使用真正舊項目的代碼所獲得的結果。 – Demo41357

回答

1

原來我是在我的MediaMetaData對象中捕捉到錯誤的異常,所以當它到達沒有正確初始化的文件時,它會向我的循環中拋出一個RunTime異常,從而結束循環本身。