xRobot xRobot - 1 month ago 10
Java Question

java.lang.IllegalThreadStateException: Thread already started

I am developing a simple music player. So there is a SeekBar that is updated by the Thread. But when I select a song for the second time, then it crashes ( java.lang.IllegalThreadStateException: Thread already started ).

This is my code:

updateSeekBar = new Thread(){
@Override
public void run(){
int totalDuration = mp.getDuration();
int currentPosition = 0;
while(mp != null && currentPosition<totalDuration){
try{
sleep(500);
currentPosition = mp.getCurrentPosition();
sb.setProgress(currentPosition);
}catch (InterruptedException e){
Log.i(TAG, "Thread ERROR" );
e.printStackTrace();
}
}

}
};


...

lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//Log.i(TAG, "Thread State: " + updateSeekBar.getState().toString());
Uri u = Uri.parse(songList.get(position).getPath().toString());
if(mp!=null){ mp.stop(); mp.reset(); mp.release(); }
mp = MediaPlayer.create(getApplicationContext(), u);
mp.start();
sb.setMax(mp.getDuration());
updateSeekBar.start();
sb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser){

}

@Override
public void onStartTrackingTouch(SeekBar seekBar){


}

@Override
public void onStopTrackingTouch(SeekBar seekBar){
mp.seekTo(seekBar.getProgress());
}
});


How could I avoid the crash ?

Answer

How could I avoid the crash ?

don't use a Thread for this kind of task. Every view has a Handler. You can use it to post a runnable with delay that updates your seekbar. E.g.

public class MyUpdater implements Runnable {

   MediaPlayer mp;
   SeekBar sb;

   public MyUpdater(MediaPlayer mp, SeekBar sb) {
        this.mp = mp;
        this.sb = sb;
   }

   @Override
   public void run(){
     int totalDuration = mp.getDuration();
     int currentPosition = mp.getCurrentPosition();
     if (currentPosition<totalDuration) {
        sb.removeCallbacks(this);
        return;
     }   
     sb.setProgress(currentPosition);
     sb.postDelayed(this, 500);
  }  
}

Keep MyUpdater as member,

 final MyUpdater mUpdater;

and onItemClick just do

 sb.removeCallbacks(mUpdater);
 mUpdater = new MyUpdater(mp, sb);
 sb.post(mUpdater);