Вопрос

Here is my case, I launch a different dialog for each song, which has "play" button and a progressBar as follows
enter image description here

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]);       
    }
}
Это было полезно?

Решение

I've solved that by making my progressBar static

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top