Here is my case, I launch a different dialog for each song, which has "play" button and a progressBar as follows
when I launch the first song it plays well and the progreesBar updates, but when playing second song (second dialog) the song plays but progressBar won't update, until I pause and resume again!
I've traced my problem and I've found that some message handler won't update the dialog reference no matter what I do, here is my code.
SongDetail.java
@Override
public void onClick(View v)
{
switch (v.getId())
{
case R.id.song_detail_but_play:
ProgressBar progressBar= (ProgressBar)findViewById(R.id.song_detail_progress);
Log.v("", "***********************");
Log.v("onclick", progressBar+"");
musicPlayer.setProgressBar(progressBar);
musicPlayer.togglePlay(previewURL);
break;
}
MusicPlayer.java
public class MusicPlayer implements OnCompletionListener, OnPreparedListener, OnErrorListener
{
// all static will be data member and class will be singleton later
private static MediaPlayer mediaPlayer;
private static boolean playing;
private static String currnetMediaUrl=null;
private ProgressBar progressBar;
private Thread thread;
private Handler handler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
progressBar.setProgress(msg.arg1);
Log.v("handler", progressBar+"");
}
};
public void setProgressBar(ProgressBar progressBar)
{
Log.v("from set progress", progressBar+"");
this.progressBar=null;
this.progressBar = progressBar;
Log.v("from set progress member ", this.progressBar+"");
}
public MusicPlayer()
{
setPlaying(false);//
if( mediaPlayer ==null )
{
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnCompletionListener(this);
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setOnErrorListener(this);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
}
}
@Override
public boolean onError(MediaPlayer arg0, int arg1, int arg2)
{
//stop();
setPlaying(false);
killThread();
return false;
}
@Override
public void onPrepared(MediaPlayer arg0)//
{
mediaPlayer.start();
fireThread();
}
@Override
public void onCompletion(MediaPlayer arg0)
{ setPlaying(false);killThread(); }
public void play(String url)
{
boolean isChanged = changeMedia(url);
if ( isChanged ) // media has changed therefore need to prepare again
mediaPlayer.prepareAsync();
else
{mediaPlayer.start();fireThread();}//no need to prepare and play directly
setPlaying(true);
}
public void stop()
{
mediaPlayer.pause();
setPlaying(false);
killThread();
}
public void togglePlay(String url)
{
if ( isPlaying() )
stop();
else
play(url);
}
public void fireThread()
{
Runnable runnable = new Runnable()
{
@Override
public void run()
{
//Looper.prepare();
int duration = mediaPlayer.getDuration();
int pos=0;
while( mediaPlayer.isPlaying() )
{
pos=mediaPlayer.getCurrentPosition();
Message msg = new Message();
msg.arg1 = Math.round(((pos/(duration*1.0f))*100));
if ( duration-pos<500 )
msg.arg1=100;
handler.dispatchMessage(msg);
try
{ Thread.sleep(500,0); }
catch (InterruptedException e)
{ }
}
}
};
thread= new Thread(runnable);
thread.start();
}
}
Upon prints, in my logcat i get
for the first song
********************************
onclick progReference1
from set progress progReference1
from set progress member progReference1
from handler progReference1
for the second song
********************************
onclick progReference2
from set progress progReference2
from set progress member progReference2
from handler progReference1
for the second song after pause then resume
********************************
onclick progReference2
from set progress progReference2
from set progress member progReference2
from handler progReference2
Any idea?
------EDIT------
I''ve updated the code to use AsyncTask still facing same problem :(
MusicPlayer.java
public void fireThread() //fireThread() just creates a new AsyncTask now
{
thread= new StreamUpdate(progressBar);
thread.execute(null);
}
StreamUpdate .java
public class StreamUpdate extends AsyncTask<String, Integer, String>
{
ProgressBar progressBar;
public StreamUpdate(ProgressBar progressBar)
{
this.progressBar=progressBar;
}
@Override
protected String doInBackground(String... params)
{
{
int duration = MusicPlayer.getMediaPlayer().getDuration();
int pos=0;
int percent=0;
while( MusicPlayer.getMediaPlayer().isPlaying() )
{
pos = MusicPlayer.getMediaPlayer().getCurrentPosition();
percent = Math.round(((pos/(duration*1.0f))*100));
if ( duration-pos<500 )
percent=100;
publishProgress(percent);
try
{ Thread.sleep(500,0); }
catch (InterruptedException e)
{ }
}
}
return null;
}
@Override
protected void onProgressUpdate(Integer... progress)
{
super.onProgressUpdate(progress);
progressBar.setProgress(progress[0]);
}
}