3

ListView があり、行をクリックするとサウンドが再生されます。

サウンドが再生されているときに別の行をクリックすると、最初の行が停止し、2 番目の行が開始されます。

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

プレイ終了時にアクションを行う必要がない場合。SoundPool の使用を検討してください: http://developer.android.com/reference/android/media/SoundPool.html

于 2014-01-08T19:47:01.807 に答える
1

MediaPlayer を再度作成する理由

を使用してファイルを設定できます'setDataSource'。ここを参照してください: Android 開発者の Web サイト: MediaPlayer

例はこちら

于 2012-10-04T13:02:13.657 に答える
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 に答える