这是我的情况,我为每首歌曲启动了一个不同的对话框,其中有“播放”按钮和一个进度条,如下所示
当我启动第一首歌曲时它播放良好并且progreesBar更新,但是在播放第二首歌曲(第二个对话框)时歌曲播放但progressBar不会更新,直到我暂停并再次恢复!我跟踪了我的问题,发现无论我做什么,一些消息处理程序都不会更新对话框引用,这是我的代码。
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;
}
音乐播放器.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();
}
}
打印后,在我的 logcat 中我得到
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
任何的想法?
- - - 编辑 - - -
我已经更新了代码以使用 AsyncTask 仍然面临同样的问题:(
音乐播放器.java
public void fireThread() //fireThread() just creates a new AsyncTask now
{
thread= new StreamUpdate(progressBar);
thread.execute(null);
}
流更新.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]);
}
}