【问题标题】:Playing and Releasing audio in RecyclerView在 RecyclerView 中播放和释放音频
【发布时间】:2017-09-06 21:03:31
【问题描述】:

我正在学习 android,目前正在学习 RecyclerView,所以在这个例子中,我在单击播放按钮时播放特定的原始声音文件,然后在完成后释放它。 我可以认真地使用一些关于最佳实践的指示,但是因为我有一些问题和疑问:

  • 我在转换状态时遇到问题,所以如果我很快按下播放键,我会收到 IllegalStateException,可能是因为试图释放已发布的播放器。
  • 我显然也应该在发布后取消并事先进行 null 检查,但由于我在嵌套范围内使用它,因此必须将其声明为最终且不能为空,这会造成混淆,我显然错过了什么。
  • onBindViewHolder 中的项目上设置 clickListner 似乎也比在 viewHolder 类中的整行上添加 clickListner 慢得多,响应速度也慢。

设置 mediaPlayer 和使用 RecyclerView 正确管理资源的最佳做法是什么?我做错了什么会导致崩溃和“缓慢”?

//ViewHolder

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();
                }
            });
        }
    });
}

【问题讨论】:

  • 你为什么要“收听”媒体播放器?如果您需要对用户交互做出反应,为什么不添加两个侦听器:onLongClick() 和 onClick()。 LongClick 可以启动,当用户停止按下时,会自动调用 onClick(),您可以在此处停止播放。
  • 其实我不需要停止播放,我使用的声音文件只有1-2s长。 setOnCompleteListener 是这样的,当文件播放完毕时,它会释放所有资源,如果这就是你的意思。
  • 在全局或活动或适配器中声明 MediaPlayer - 将 MediaPlayer 的实例传递给 Viewholder 并尝试它应该工作的相同。

标签: java android android-recyclerview android-mediaplayer


【解决方案1】:

如果您只是在听用户交互,您可以删除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
        }
    });

【讨论】:

  • @LuckyXII 有帮助吗?
  • 对不起,它可能已经解决了足够快的点击会尝试释放已经释放的资源并抛出非法状态异常的问题,但这只是因为 longClick 延迟允许进程完成(我不是完全确定这是原因)。然而,由于音频文件只有 1-2 秒长,因此 longClick 等待时间太长了,无法让人感觉流畅,也不能真正解决问题。我确实找到了一个我认为可能可行的解决方案,但由于我是提出它的人,而且我是绝对的菜鸟,我不能说这是否是“好的”做法
  • 好吧,onLongClick 应该立即执行播放声音。无论如何感谢您的反馈。祝你好运!
  • 感谢我一直以来的帮助!我已经发布了我的“解决方案”,以便澄清我的问题
【解决方案2】:

OBS 当我回答我自己的问题时,我不能说这确实是一种好的做法,但它确实解决了我遇到的问题,如果有人发现错误或有更好更有效的方法,请发布答案并详细说明。

  • 我没有在 onBindViewHolder 中声明 MediaPlayer,而是将它设置为一个类变量,这样我就可以避免让它成为 final,并且能够在发布后将其取消。
  • 然后我在 onClick 方法中定义了它,以确保它永远不会为空,并且总是在需要时声明。
  • 为了在 onClick 中使用它们,我必须将我的持有者和“项目”设为最终版本,但这似乎奏效了(我猜是 recyclerView 魔术)

应用程序不再崩溃并且 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);
            }
        }
    });
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-03
    • 2016-01-21
    相关资源
    最近更新 更多