在recyclerview中播放和释放音频

zd287kbt  于 2021-07-03  发布在  Java
关注(0)|答案(2)|浏览(587)

我正在学习android和recyclerview,所以在这个示例中,我在单击播放按钮时播放一个特定的原始声音文件,然后在播放完成后将其释放。我可以认真使用一些关于什么是最佳实践的建议,但是我有一些问题:
我在状态转换上有个问题,所以如果我很快按play,我会得到一个illegalstateexception,可能是因为试图释放一个已经释放的玩家。
我显然也应该在发布后取消它,并在发布前做一个空检查,但由于我在嵌套范围中使用它,它必须声明为final,不能取消它,这很混乱,我显然错过了一些东西。
与在viewholder类的整行上添加clicklistner相比,在onbindviewholder中的项目上设置clicklistner似乎要慢得多,响应性也要差得多。
使用recyclerview设置mediaplayer和正确管理资源的最佳实践是什么?我做错了什么会导致崩溃和“缓慢”?
//取景器

public static class myHolder extends RecyclerView.ViewHolder implements View.OnClickListener{

    ImageView playBtn;

    public myHolder(View v){
        super(v);
        playBtn = (ImageView) v.findViewById(R.id.playBtn);
        v.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
    }

}

//onbindviewholder/oncompletionlistener

@Override
public void onBindViewHolder(myHolder holder, int position) {
    myClass item = itemList.get(position);
    final MediaPlayer mediaPlayer = MediaPlayer.create(holder.itemView.getContext(), item.getAudioSource());

   holder.playBtn.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View v) {

            mediaPlayer.start();
            mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    mp.release();
                }
            });
        }
    });
}
2cmtqfgy

2cmtqfgy1#

如果您只在用户交互中侦听,则可以删除 setOnCompleteListener() 而是按(顺序)定义播放/停止代码 OnLongClickListener() 以及 OnClickListener . 这样地:

holder.playBtn.setOnClickListener(new View.OnClickListener(){
    @Override
    public void onClick(View v) {
       //Code to stop playing and release resources
    }
});

holder.playBtn.setOnLongClickListener(new View.OnClickListener(){
        @Override
        public void onLongClick(View v) {
           //Code to start playing 

           return false; //!!This is important so that OnClick() would be called after releasing the button
        }
    });
zaqlnxep

zaqlnxep2#

obs由于我在回答我自己的问题,我不能说这是一个很好的做法,但它确实解决了我的问题,如果有人发现一个错误或有一个更好更有效的方法,那么请张贴一个答案和详细说明。
我没有在onbindviewholder中声明mediaplayer,而是将其作为类变量,这样可以避免将其设置为final,并在发布后使其无效。
然后我在onclick方法中定义了它,以确保它永远不会为null,并且在需要时总是被声明。
为了在onclick中使用它们,我不得不将我的holder和“item”设置为final,但这似乎奏效了(我猜是recyclerview magic)
应用程序不再崩溃,oncompletionlistener应清除所有资源,这是当前代码:
//类变量mediaplayer和oncompletionlistener方法

MediaPlayer mediaPlayer;

//onCompletionListener method
MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener() {
    @Override
    public void onCompletion(MediaPlayer mp) {
        mp.release();
        mediaPlayer = null;
    }
};

//onbindviewholder

@Override
public void onBindViewHolder(final itemHolder holder, int position) {
    final Items item = mItemList.get(position);

    holder.playBtn.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View v) {
            mediaPlayer = MediaPlayer.create(holder.itemView.getContext(), item.getAudioSource());
            if(mediaPlayer != null) {
                mediaPlayer.start();
                mediaPlayer.setOnCompletionListener(mCompletionListener);
            }
        }
    });
}

相关问题