在 stop() 和 prepareAsync() 之后未调用 MediaPlayer onPrepared() 的问题

Problem with MediaPlayer onPrepared() not being called after stop() and prepareAsync()

我首先将媒体播放器加载到合成中 class:

public class MediaPlayerWURI {

    private final MediaPlayer mediaPlayer;

    final Uri uri;

    final ActivityMain activityMain;

    boolean isPrepared = true;

    MediaPlayerWURI(ActivityMain activityMain, MediaPlayer mediaPlayer, Uri uri){
        this.activityMain = activityMain;
        this.mediaPlayer = mediaPlayer;
        this.uri= uri;
        mediaPlayer.setOnPreparedListener(null);
        mediaPlayer.setOnErrorListener(null);
        mediaPlayer.setOnPreparedListener(new MOnPreparedListener(this));
        mediaPlayer.setOnErrorListener(new MOnErrorListener());
    }

    public void prepareAsync(){
        isPrepared = false;
        mediaPlayer.prepareAsync();
    }

    public void start(){
        mediaPlayer.start();
    }

    public void stop(){
        isPrepared = false;
        mediaPlayer.stop();
    }

    class MOnPreparedListener implements MediaPlayer.OnPreparedListener{

        final MediaPlayerWURI mediaPlayerWURI;

        public  MOnPreparedListener(MediaPlayerWURI mediaPlayerWURI){
            this.mediaPlayerWURI = mediaPlayerWURI;
        }

        @Override
        public void onPrepared(MediaPlayer mediaPlayer) {
            mediaPlayerWURI.isPrepared = true;
        }
    }

    class MOnErrorListener implements MediaPlayer.OnErrorListener {

        public MOnErrorListener(){
        }

        @Override
        public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {
                activityMain.releaseMediaPlayers();
                return false;
        }

    }

}

传入的媒体播放器是用MediaPlayer.create(getApplicationContext())创建的,并且启动成功。

以下代码不会触发 onPrepared() 并陷入循环。

 mediaPlayerWURI.stop();
 mediaPlayerWURI.prepareAsync();
 while (!mediaPlayerWURI.isPrepared) { }
 mediaPlayerWURI.start();

我已经在另一个线程上尝试 prepareAsync()

executorService.submit(new Runnable() {
                        @Override
                        public void run() {
                            mediaPlayerWURI.prepareAsync();
                        }
                    });

我猜这是一个线程问题,但我不确定如何处理这个问题,或者它是否是一个线程问题。我的理解是 MediaPlayer 正在另一个线程中准备,并且循环不应该阻止它调用准备好的。我不确定 onPrepare() 是在哪个线程 运行 上,但是从上面来看,我认为这意味着主线程应该 运行 onPrepare() 并且正在等待循环结束。

此外,在构建 MediaPlayer 后调用 onPrepared() 时,我遇到了奇怪的行为。那是正常的吗?我的假设是在准备好的 MediaPlayer 上调用 setOnPrepared() 时调用 onPrepared()。这意味着侦听器已附加。

问题是在等待 MediaPlayer 准备好时 while (!mediaPlayerWURI.isPrepared) { },我正在占用 UI 线程,这与 onPrepared() 使用的线程相同。

为了解决这个问题,我不得不停止占用 UI 线程。我在我的 MediaPlayerWURI 包装器 class 中添加了一个布尔值,指示在准备好的情况下播放 MediaPlayer。

private final MediaPlayer mediaPlayer;
volatile boolean isPrepared;
volatile boolean shouldPlay;

synchronized public void shouldStart(boolean shouldPlay){
    if(shouldPlay && isPrepared){
        mediaPlayer.start();
    } else {
        this.shouldPlay = shouldPlay;
    }
}

@Override
public void onPrepared(MediaPlayer mediaPlayer) {
    synchronized (mediaPlayerWURI) {
        mediaPlayerWURI.isPrepared = true;
        if (shouldPlay) {
            mediaPlayer.start();
            shouldPlay = false;
        }
    }
}