2016-08-15 4 views
1

Android에서 뮤직 플레이어 앱을 만들고 있는데 기기의 노래 목록을로드하는 데 문제가 있습니다 빨리. 이 노래는 약 6.8-7 초 안에 577 곡을로드하는데, 너무 길다. 어떤 팁? 느린 음악로드 알고리즘

나는 다음과 같은 정보를 얻으려고 : 노래를

  • 노래 이름
  • 노래 아티스트
  • 앨범 이름
  • 노래 ID는 벨소리 나 알림 (에 든
  • 그것을 무시하십시오)

그녀 음악 플레이어에 대한 첫 번째 화면이 노래의 목록이기 때문에, 나는 처음에이 목록을로드하기 위해 노력하고있어

public static ArrayList<Song> getSongList(Activity activity, String artistBound, Album albumBound) { 
    long start = System.currentTimeMillis(); 
    ArrayList<Song> songList = new ArrayList<>(); 
    ContentResolver musicResolver = activity.getContentResolver(); 
    Uri musicUri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; 
    Cursor musicCursor = musicResolver.query(musicUri, null, null, null, null); 

    if(musicCursor!=null && musicCursor.moveToFirst()){ 
     //get columns 
     int titleColumn = musicCursor.getColumnIndex 
       (android.provider.MediaStore.Audio.Media.TITLE); 
     int idColumn = musicCursor.getColumnIndex 
       (android.provider.MediaStore.Audio.Media._ID); 
     int artistColumn = musicCursor.getColumnIndex 
       (android.provider.MediaStore.Audio.Media.ARTIST); 
     int albumIdColumn = musicCursor.getColumnIndex 
       (MediaStore.Audio.Media.ALBUM_ID); 
     int ringColumn = musicCursor.getColumnIndex(MediaStore.Audio.Media.IS_RINGTONE); 
     int notifColumn = musicCursor.getColumnIndex(MediaStore.Audio.Media.IS_NOTIFICATION); 
     //add songs to list 
     do { 
      long thisId = musicCursor.getLong(idColumn); 
      String thisTitle = musicCursor.getString(titleColumn); 
      Artist thisArtist = new Artist(musicCursor.getString(artistColumn)); 
      if(artistBound != null && !thisArtist.getName().equals(artistBound)) continue; 

      long albumId = musicCursor.getLong(albumIdColumn); 
      Cursor albumCursor = activity.getContentResolver().query(
        MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, 
        new String[]{MediaStore.Audio.Albums.ALBUM_ART, MediaStore.Audio.Albums.ALBUM}, 
        MediaStore.Audio.Albums._ID + " = ?", 
        new String[]{Long.toString(albumId)}, 
        null 
      ); 
      boolean queryResult = albumCursor.moveToFirst(); 
      String albumCover = null; 
      String albumName = null; 
      Album album = null; 
      if (queryResult) { 
       albumCover = albumCursor.getString(0); 
       albumName = albumCursor.getString(1); 
       album = new Album(albumName, albumCover); 
      } 
      albumCursor.close(); 

      if(musicCursor.getInt(ringColumn) > 0 || musicCursor.getInt(notifColumn) > 0) { 

      } else { 
       if(albumBound == null || albumBound.getName().equals(album.getName())) { 
        songList.add(new Song(thisId, thisTitle, thisArtist, album)); 
       } 
      } 
     } 
     while (musicCursor.moveToNext()); 
    } 
    Collections.sort(songList); 

    Log.d("app", "Got " + songList.size() + " songs in: " + (System.currentTimeMillis() - start) + "ms"); 
    return songList; 
} 

문제는 다음과 같습니다 전자 내 현재의 알고리즘이다. 하지만 지금 당장은로드하려고 시도 할 때이 화면에 앱이 멈 춥니 다.

편집 : 앨범 정보를 검색하는 코드를 제거하면 매우 빠르게 실행됩니다. 앨범 정보 검색을 최적화하려면 어떻게해야합니까?

+2

결과를 캐시하고 새 파일 만 찾습니다. –

+0

비동기 작업에서 실행하고 songList.add를 사용하여 publishProgress (노래 노래)를 사용하면 UI가 응답을 유지하고 즉시 노래를 표시하기 시작합니다. – Linxy

답변

2

하나의 솔루션은 지연로드 방법을 사용하는 것입니다. 아이디어는 모든 항목을로드하지 않고 데이터 세트의 절반을 말하게하는 것입니다. 귀하의 경우 로딩 시간이 크게 줄어 듭니다. 인터넷에서 서버에서 이미지를 가져 와서 표시하는 몇 가지 지연로드 구현을 찾을 수 있습니다. 대신 로컬 저장소에서 노래를 읽는 방식으로 편집 할 수 있습니다. 수락 된 대답 here을 확인하십시오.