为什么 setOnCompletionListener 只被调用一次?

Why setOnCompletionListener is being called only once?

我正在制作一个音乐应用程序来提高我的技能,我希望它使用 setOnCompletionListener 方法自动播放歌曲。但是只运行一次,song1进入song2就不会进入song3了。

我将 setOnCompletionListener 放在我的 onCreate 方法中,如下所示:

mySong.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
    @Override
    public void onCompletion(MediaPlayer mediaPlayer) {
        nextSong();
    }
});

这是我的nextSong()方法:

public void nextSong() {
    ifPlaying = true; //for displaying purposes
    displayPP();     //for displaying purposes

    //if switch is checked, randomize songs
    if (mySwitch.isChecked()) {
        musicCounter = dice.nextInt(songNumbers);
        Toast.makeText(getApplicationContext(), Integer.toString(musicCounter), Toast.LENGTH_SHORT).show();
        mySong.reset();
        playMusic();
    } else {
        if (musicCounter < songNumbers - 1) {
            musicCounter++;
            mySong.reset();
            playMusic();
        } else {
            Toast.makeText(getApplicationContext(), "No more songs", Toast.LENGTH_SHORT).show();
        }
        if (test.equalsIgnoreCase("Jason Mraz")) {
            displaySong(jm);
        } else if (test.equalsIgnoreCase("fob")) {
            displaySong(fob);
        } else if (test.equalsIgnoreCase("ed")) {
            displaySong(ed);
        }
    }
}

playMusic 方法,以防您想知道:

public void playMusic() {

    //test is intent.putExtra to know what index was clicked on my listview

    if(test.equalsIgnoreCase("Jason Mraz")) {
        mySong = MediaPlayer.create(MusicClass.this, jm[musicCounter]);
        displaySong(jm);
        songNumbers = jm.length;
        mySong.start();

    } else if(test.equalsIgnoreCase("fob")) {
        mySong = MediaPlayer.create(MusicClass.this, fob[musicCounter]);
        displaySong(fob);
        songNumbers = fob.length;
        mySong.start();
    } else if(test.equalsIgnoreCase("ed")) {
        mySong = MediaPlayer.create(MusicClass.this, ed[musicCounter]);
        displaySong(ed);
        songNumbers = ed.length;
        mySong.start();
    }
}

而且,我一直在使用 nextSong();我的下一个按钮上的方法,它工作得很好。所以我想知道为什么它只在 setOnCompletionListener() 中执行一次;方法。这是我的下一个按钮的代码:

public void nextClicked(View view) {
    nextSong();
}

那是因为您只设置了一次 onCompletionListener,然后,每当您调用 playMusic() 时,您就会覆盖 mySong 值,并且您再也不会设置 onCompletionListener

解决问题的一种方法是按如下方式修改 playMusic() 方法:

public void playMusic() {
    if(test.equalsIgnoreCase("Jason Mraz")) {
        mySong = MediaPlayer.create(MusicClass.this, jm[musicCounter]);
        displaySong(jm);
        songNumbers = jm.length;
    }else if(test.equalsIgnoreCase("fob")) {
        mySong = MediaPlayer.create(MusicClass.this, fob[musicCounter]);
        displaySong(fob);
        songNumbers = fob.length;
    }else if(test.equalsIgnoreCase("ed")) {
        mySong = MediaPlayer.create(MusicClass.this, ed[musicCounter]);
        displaySong(ed);
        songNumbers = ed.length;
    }
    mySong.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mediaPlayer) {
           nextSong();
        }
    });
    mySong.start();
}