2016-07-03 74 views
0

我正在製作一個應用程序,它可以掃描手機存儲中的歌曲列表,並將它們存儲在ListView中。因此,我創建了類SongsManager,它掃描SD卡中的歌曲並將它們存儲在Array中。代碼如下所示。線程 - 如何提高應用程序的性能

public class SongsManager { 
final String MEDIA_PATH = Environment.getExternalStorageDirectory() .getPath() + "/"; 
private ArrayList<HashMap<String, String>> songsList = new ArrayList<HashMap<String, String>>(); 
private String mp3Pattern = ".mp3"; 
private File directory; 

// Constructor 
public SongsManager() { 
} 

/** * Function to read all mp3 files and store the details in * ArrayList * */ 

public ArrayList<HashMap<String, String>> getPlayList() { 
      System.out.println(MEDIA_PATH); 
      if (MEDIA_PATH != null) { 
       File home = new File(MEDIA_PATH); 
       File[] listFiles = home.listFiles(); 
       if (listFiles != null && listFiles.length > 0) { 
        for (File file : listFiles) { 
         System.out.println(file.getAbsolutePath()); 
         if (file.isDirectory()) { 
          scanDirectory(file); 
         } else { 
          addSongToList(file); 
         } 
        } 
       } 
      } 
    return songsList; 
} 


private void scanDirectory(final File directory) { 
      if (directory != null) { 
       File[] listFiles = directory.listFiles(); 
       if (listFiles != null && listFiles.length > 0) { 
        for (File file : listFiles) { 
         if (file.isDirectory()) { 
          scanDirectory(file); 
         } else { 
          addSongToList(file); 
         } 
        } 
       } 
      } 
    } 


private void addSongToList(File song) { 
    if (song.getName().endsWith(mp3Pattern)) { 
     HashMap<String, String> songMap = new HashMap<String, String>(); 
     songMap.put("songTitle", song.getName().substring(0, (song.getName().length() - 4))); 
     songMap.put("songPath", song.getPath()); 

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

當我運行該應用程序時,由於從SD卡提取歌曲,應用程序凍結2或3秒。當我打開logcat時,它顯示錯誤The application may be doing too much work on its main thread。所以,我決定改善應用程序的性能。我修改了以下類:

public class SongsManager { 

final String MEDIA_PATH = Environment.getExternalStorageDirectory() .getPath() + "/"; 
private ArrayList<HashMap<String, String>> songsList = new ArrayList<HashMap<String, String>>(); 
private String mp3Pattern = ".mp3"; 
private File directory; 

// Constructor 
public SongsManager() { 
} 

/** * Function to read all mp3 files and store the details in * ArrayList * */ 

public ArrayList<HashMap<String, String>> getPlayList() { 
      System.out.println(MEDIA_PATH); 
      if (MEDIA_PATH != null) { 
       File home = new File(MEDIA_PATH); 
       File[] listFiles = home.listFiles(); 
       if (listFiles != null && listFiles.length > 0) { 
        for (File file : listFiles) { 
         System.out.println(file.getAbsolutePath()); 
         if (file.isDirectory()) { 
          scanDirectory(file); 
         } else { 
          addSongToList(file); 
         } 
        } 
       } 
      } 
    return songsList; 
} 


private void scanDirectory(final File directory) { 
    Runnable r = new Runnable() { 
     @Override 
     public void run() { 
      if (directory != null) { 
       File[] listFiles = directory.listFiles(); 
       if (listFiles != null && listFiles.length > 0) { 
        for (File file : listFiles) { 
         if (file.isDirectory()) { 
          scanDirectory(file); 
         } else { 
          addSongToList(file); 
         } 
        } 
       } 
      } 
     } 
    }; 
    Thread thread = new Thread(r); 
    thread.start(); 
} 


private void addSongToList(File song) { 
    if (song.getName().endsWith(mp3Pattern)) { 
     HashMap<String, String> songMap = new HashMap<String, String>(); 
     songMap.put("songTitle", song.getName().substring(0, (song.getName().length() - 4))); 
     songMap.put("songPath", song.getPath()); 

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

修改代碼後,凍結問題解決了,但取出的歌曲無法正常工作。當我打開應用程序時,一些歌曲會被加載,有些則不會。當我重新打開應用程序時,會加載更多歌曲。發生此問題。 這裏是我的Tab1 Class代碼

public class Tab1 extends ListFragment { 

private ListView lv; 
// Songs list 
public ArrayList<HashMap<String, String>> songsList = new ArrayList<HashMap<String, String>>(); 


public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    View V = inflater.inflate(R.layout.tab1, container, false); 

    ArrayList<HashMap<String, String>> songsListData = new ArrayList<HashMap<String, String>>(); 
    SongsManager plm = new SongsManager(); 
    // get all songs from sdcard 
    this.songsList = plm.getPlayList(); 

    // looping through playlist 
    for (int i = 0; i < songsList.size(); i++) { 
     // creating new HashMap 
     HashMap<String, String> song = songsList.get(i); 
     // adding HashList to ArrayList 
     songsListData.add(song); 
    } 

    // Adding menuItems to ListView 
    ListAdapter adapter = new SimpleAdapter(getContext(), songsListData, 
      R.layout.playlist_item, new String[]{"songTitle"}, new int[]{ 
      R.id.songTitle}); 
    setListAdapter(adapter); 
    return V; 
} 

}

+0

你能告訴我,你調用getPlayList()嗎? –

+0

已添加...請檢查。 –

回答

0

考慮使用的AsyncTask代替上述實施..在你執行沒有辦法保證您的plm.getPlaylist()完成,因爲它畢竟歌已掃描在幾個不同的線程上完成。這就是爲什麼你沒有看到所有歌曲。

public class GetSongsAsyncTask extends AsyncTask<Void, Void, List<Hashmap<String, String>>> { 
private final SongsManager mSongsManager; 

public interface SongsReceivedListener { 
    void onSongsReceived(List<HashMap<String, String>> songs); 
} 

private SongsReceivedListener mSongsReceivedListener; 

public GetSongsAsyncTask(SongsReceivedListener mSongsReceivedListener) { 
    this.mSongsReceivedListener = mSongsReceivedListener; 
    mSongsManager = new SongsManager(); 
} 

@Override 
protected List<HashMap<String, String>> doInBackground(Void.. voids) { 
    return mSongsManager.getPLayList(); 
} 

@Override 
protected void onPostExecute(List<HashMap<String, String>> v) { 
    if(mSongsReceivedListener != null) { 
     mSongsReceivedListener.onSongsReceived(v); 
    } 
} 
} 

如果您的列表片段將實施SongsReceivedListener並稱之爲的AsyncTask這樣

new GetSongsAsyncTask(this).execute(); 

ListFragment看起來就像這樣

公共類TAB1擴展ListFragment實現GetSongsAsyncTask.SongsReceivedListener {

私人ListView lv; //歌曲列表 public ArrayList> songsList = new ArrayList>(); public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); }

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    View V = inflater.inflate(R.layout.tab1, container, false); 
    new GetSongsAsyncTask(this).execute(); 
    return V; 
} 

@Override 
void onSongsReceived(List<Hashmap<String, String>> songs) { 
    if(getContext() == null) 
    return; 
    // looping through playlist 
    for (int i = 0; i < songsList.size(); i++) { 
     // creating new HashMap 
     HashMap<String, String> song = songs.get(i); 
     // adding HashList to ArrayList 
     songsListData.add(song); 
    } 

    // Adding menuItems to ListView 
    ListAdapter adapter = new SimpleAdapter(getContext(), songsListData, 
      R.layout.playlist_item, new String[]{"songTitle"}, new int[]{ 
      R.id.songTitle}); 
    setListAdapter(adapter); 
} 

} 
+0

@AkshaySharma這就是我所做的。讓我試着添加更多的細節 –

+0

@AkshaySharma增加了更多的實現 –

+0

謝謝先生。 。請稍等...我會盡力回覆你。再次感謝 –