2

就我而言,我想流式传输音频并在简单的 ProgressBar 上显示其进度,我找不到用于播放进度的事件处理程序,我在互联网上发现的只是我可以制作一个 Runnable 并在 play() 上触发它跟随

public void fireRunnable()
{
    Runnable runnable = new Runnable()
    {
        @Override
        public void run()
        {
            int duration = mediaPlayer.getDuration();
            while( mediaPlayer.isPlaying() )
            {
                Log.v("", mediaPlayer.getCurrentPosition()+"");
            }
        }
    };
    runnable.run();
}

并在 onPrepared() 播放后立即调用它

@Override
public void onPrepared(MediaPlayer arg0)
{
    arg0.start();
    fireRunnable();
}

现在这首歌开始时没有音频并且应用程序在 5 秒后崩溃,这是一个好方法吗,如果是,我怎样才能让它工作?或者没有我还有什么其他选择?
帮助将不胜感激。

4

1 回答 1

5

如果您选择使用Runnable如图所示的 a,您将希望在另一个中运行它Thread并用于post(Runnable)在 UI 线程上进行更改。您提到的崩溃可能是因为您的 UI 线程上有一个非常活跃的 while 循环。即使启动一个单独的线程,您也需要Thread.sleep(long)在循环中调用以产生一些处理器时间,因为您的进度条不需要如此精确。

另一种方法是使用在一些小的延迟(例如,500 毫秒)后重复重新发布自身postDelayed(Runnable, long)的 a 。Runnable根据情况,这种方法可能是首选,因为它避免了额外的线程。

另外,您应该注意,如果暂停,这isPlaying()将是错误的。MediaPlayer最好使用布尔成员作为停止更新进度条的条件。在开始更新进度条之前将其设置为 true,并OnCompletionListener.onCompletion()MediaPlayer.

编辑:

当我提到post(Runnable)UI 线程时,我指的是从其他线程对 UI 元素进行更改是非法的。在这种情况下,您可能没有显式更改 UI 元素,只是更改了进度条的状态,这应该没问题。

编辑:(postDelayed版本)

在你的Activity

private boolean mUpdateProgress = false;
private Runnable mUpdateRunnable = new Runnable() {
    @Override
    public void run() {
        // update progress bar using getCurrentPosition()
        if (mUpdateProgress)
            postDelayed(mUpdateRunnable, 500);
    }
}
private MediaPlayer.OnCompletionListener mComplete =
    new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion() {
            mUpdateProgress = false;
        }
    }

无论您在哪里创建MediaPlayer,请致电:

mediaPlayer.setOnCompletionListener(mComplete);

无论您从哪里开始MediaPlayer,请执行以下操作:

// update the duration of the progress bar
mUpdateProgress = true;
post(mUpdateRunnable); // or simply mRunnable.run() if you are on the main thread
mediaPlayer.start();
于 2013-10-02T03:01:02.377 回答