Android Handler无法更新progressBar参考

时间:2013-10-02 10:13:08

标签: android multithreading android-asynctask android-handler

以下是我的情况,我为每首歌创建了一个不同的对话框,其中包含“播放”按钮和一个progressBar,如下所示enter image description here

当我发布第一首歌时它播放得很好并且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;
}

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();
    }
}

打印完成后,在我的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

有什么想法吗?

------ ------ EDIT

我已更新代码以使用仍然面临同样问题的AsyncTask :(

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]);       
    }
}

1 个答案:

答案 0 :(得分:0)

我通过使我的progressBar静态

解决了这个问题