Android-从另一个类调用时,MediaPlayer将不会释放

时间:2018-12-03 22:28:01

标签: java android android-mediaplayer

我有一个RecyclerView,其中添加了元素,然后单击它们可以播放声音。如果我在Adapter类中创建所有MediaPlayer方法,则所有内容都会正确释放,并且一次只能播放一个音频。

//this works (code in the adapter class)
private MediaPlayer mMediaPlayer;

//release if not playing
public void releaseMediaPlayer() {
    // if no sound is playing
    if (mMediaPlayer != null) {
        Log.d("rEEEEEEEEEEEEEEEEEEE", "releaseMediaPlayer: ");
        mMediaPlayer.release();
        mMediaPlayer = null;
    }
}

//release media player on sound finish
public MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener() {
    @Override
    public void onCompletion(MediaPlayer mediaPlayer) {
        releaseMediaPlayer();
    }
};
// on click listener code
releaseMediaPlayer();
mMediaPlayer = MediaPlayer.create(context, word.getmAudioResourceId());
mMediaPlayer.start();
mMediaPlayer.setOnCompletionListener(mCompletionListener);

但是,如果我使用单独的类,则每当我调用release方法时,它都不会在一开始就释放,因此会同时播放多种声音。通常会在onCompletion上释放

public class MediaPlay {
private MediaPlayer mMediaPlayer;

public void setmMediaPlayer(MediaPlayer mMediaPlayer) {
    this.mMediaPlayer = mMediaPlayer;
}

public MediaPlayer getmMediaPlayer() {
    return mMediaPlayer;
}

//release if not playing
public void releaseMediaPlayer() {
    // if no sound is playing
   if (mMediaPlayer != null) {
        Log.d("rEEEEEEEEEEEEEEEEEEEEEEEEEEE", "releaseMediaPlayer: ");
        mMediaPlayer.release();
        mMediaPlayer = null;
    }
}

//release media player on sound finish
public MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener() {
    @Override
    public void onCompletion(MediaPlayer mediaPlayer) {
        releaseMediaPlayer();
    }
};

}

使用类时

onclicklistener

final MediaPlay m = new MediaPlay();
m.releaseMediaPlayer(); 
m.setmMediaPlayer(MediaPlayer.create(context, word.getmAudioResourceId()));
m.getmMediaPlayer().start();
m.getmMediaPlayer().setOnCompletionListener(m.mCompletionListener);

我尝试在clickListener之外创建MediaPlay对象,但没有结果。我基本上是想创建一个单独的类,以便可以从我的ACtivities调用它,以便可以将声音停止为onStop方法。 任何输入将不胜感激。

使用点击侦听器编辑1个整个观看者

    MediaPlay m;
    public ViewHolder(@NonNull View itemView) {
        super(itemView);
        //play specific sound for each list item
        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d("ViewHolder: ", String.valueOf(getAdapterPosition()));
                Word word = Words.get(getAdapterPosition());
                if (word.hasAudio()) {

                    /*releaseMediaPlayer(); // stop multiple playbacks at once
                    mMediaPlayer = MediaPlayer.create(context, word.getmAudioResourceId());
                    mMediaPlayer.start();
                    mMediaPlayer.setOnCompletionListener(mCompletionListener); //cleanup*/

                    if (m != null)
                        m.releaseMediaPlayer();

                    m = new MediaPlay();
                    //m.releaseMediaPlayer(); //TODO still plays duplicate sounds, release method not working when called like this
                    m.setmMediaPlayer(MediaPlayer.create(context, word.getmAudioResourceId()));
                    m.getmMediaPlayer().start();
                    m.getmMediaPlayer().setOnCompletionListener(m.mCompletionListener);
                }
            }
        });

        name = itemView.findViewById(R.id.nameT);
        type = itemView.findViewById(R.id.typeT);
        img = itemView.findViewById(R.id.imgV);
    }

1 个答案:

答案 0 :(得分:0)

我已经使用回调修改了您的源代码。

请仔细查看MyViewHolder类和MyAdapter的onCreateViewHolder方法:)。

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
    private Context mContext;
    private String[] mDataSet;
    private MediaPlayer mMediaPlayer;

    public static class MyViewHolder extends RecyclerView.ViewHolder {
        private TextView mTextView;
        private OnMediaPlayRequestedListener mOnMediaPlayRequestedListener;

        public MyViewHolder(TextView v, OnMediaPlayRequestedListener listener) {
            super(v);

            mTextView = v;
            mTextView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mOnMediaPlayRequestedListener != null) {
                        mOnMediaPlayRequestedListener.onMediaPlayRequested(R.raw.{resource name});
                    }
                }
            });

            mOnMediaPlayRequestedListener = listener;
        }

        private interface OnMediaPlayRequestedListener {
            void onMediaPlayRequested(int resourceId);
        }
    }

    public MyAdapter(Context context, String[] myDataset) {
        mContext = context;
        mDataSet = myDataset;
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        TextView view =
                (TextView) LayoutInflater.from(parent.getContext()).inflate(R.layout.my_text_view, parent, false);

        MyViewHolder holder = new MyViewHolder(
                view,
                new MyViewHolder.OnMediaPlayRequestedListener() {
                    @Override
                    public void onMediaPlayRequested(int resourceId) {
                        if (mMediaPlayer != null) {
                            mMediaPlayer.stop();
                            mMediaPlayer.release();
                        }

                        mMediaPlayer = MediaPlayer.create(mContext, resourceId);
                        mMediaPlayer.start();
                        mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                            @Override
                            public void onCompletion(MediaPlayer mediaPlayer) {
                                mediaPlayer.release();
                            }
                        });
                    }
                });


        return holder;
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder viewHolder, int position) {
        viewHolder.mTextView.setText(mDataSet[position]);
    }

    @Override
    public int getItemCount() {
        return mDataSet.length;
    }
}