3

我有一个 ListView,当我点击一行时,我会播放声音。

如果正在播放声音并且我单击另一行,则第一个应该停止,第二个应该开始。

如果我不释放 MediaPlayer,应用程序就会崩溃,但这会延迟下一个声音的执行。

我做错了什么?这是我的代码:

public void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);

        if(!isPlaying){
            mPlayer = MediaPlayer.create(this,soundid[position]);
            mPlayer.start();
            isPlaying = true; // reproducir es true

        }else{

            isPlaying = false;
            mPlayer.stop();
            mPlayer.reset();
            mPlayer = MediaPlayer.create(this,soundid[position]);
            mPlayer.start();
            isPlaying = true;

        }

        mPlayer.setOnCompletionListener(new OnCompletionListener() {

            public void onCompletion(MediaPlayer mPlayer) {
                mPlayer.release();
                isPlaying = false;
            }

        });
    }
4

4 回答 4

4

在这种类型的实现中,您正在创建多个媒体播放器实例,而不释放它们可能会导致异常(请参阅此处)。我建议您重新使用已经存在的媒体播放器实例。你可以通过做这样的事情来实现你的目标。

public void onListItemClick(ListView l, View v, int position, long id) {
    super.onListItemClick(l, v, position, id);

    if(!isPlaying){
        mPlayer = new MediaPlayer();
        mPlayer.setDataSource(soundid[position]);
        mPlayer.prepare();
        mPlayer.start();
        isPlaying = true;

    }else{

        isPlaying = false;
        mPlayer.stop();
        mPlayer.reset();
        mPlayer.setDataSource(soundid[position]);
        mPlayer.prepare();
        mPlayer.start();
        isPlaying = true;

    }

    mPlayer.setOnCompletionListener(new OnCompletionListener() {

        public void onCompletion(MediaPlayer mPlayer) {
            mPlayer.release();
            isPlaying = false;
        }

    });
}
于 2012-10-04T13:04:00.253 回答
1

为什么要再次创建 MediaPlayer?

您可以使用'setDataSource'. 见这里:android 开发者网站:MediaPlayer

这里的例子

于 2012-10-04T13:02:13.657 回答
1

如果您在播放完成后不需要执行任何操作;您可以考虑使用 SoundPool:http: //developer.android.com/reference/android/media/SoundPool.html

于 2014-01-08T19:47:01.807 回答
0

更清洁的实现,

public class PlayMedia{
private MediaPlayer mMediaPlayer = new MediaPlayer();
Context context;
boolean isPlaying;

PlayMedia(Context c){
    mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {

        public void onCompletion(MediaPlayer mp) {
            mp.release();
            isPlaying = false;
        }
    });
    this.context = c;
}

public boolean stopResetAndPlay(int ResID){
    if(isPlaying){
         isPlaying = false;
         mMediaPlayer.stop();
         mMediaPlayer.reset();
        try {
            AssetFileDescriptor afd = context.getResources().openRawResourceFd(ResID);
            if (afd == null) return false;
            mMediaPlayer.setDataSource(afd);
            afd.close();
            mMediaPlayer.prepare();
        }catch(IOException io){
            Log.i("Playing ", io.getMessage());
            return false;
        }
        mMediaPlayer.start();
        isPlaying = true;
    }else{
        try {
            this.mMediaPlayer = new MediaPlayer();
            AssetFileDescriptor afd = context.getResources().openRawResourceFd(ResID);
            if (afd == null) return false;
            mMediaPlayer.setDataSource(afd);
            mMediaPlayer.prepare();
            mMediaPlayer.start();
            isPlaying = true;
        }catch(IOException io){
            Log.i("Playing ", io.getMessage());
            return false;
        }
    }
    return true;
}}

这就是您可以在任何活动中使用该类的方式

PlayMedia mPlayer = new PlayMedia(context);
int resID = context.getResources().getIdentifier("identifer_string", "raw", context.getPackageName());
mPlayer.stopResetAndPlay(resID);
于 2020-01-03T12:26:33.360 回答