2017-09-04 48 views
0

我正在学习android和RecyclerView,因此在本例中,我点击播放按钮播放特定的原始声音文件,然后在播放完成后播放。 我可以认真地用的是什么,不过最好的做法,因为我有几个问题和问题的一些指针:播放和释放RecyclerView中的音频

  • 我有一个过渡状态的问题,所以如果我按得很快发挥我会得到一个IllegalStateException异常,可能来自试图释放已经发布的玩家。
  • 我应该显然也在发布后取消,并做一个null检查之前,但由于我在嵌套范围内使用它必须被宣布为最终的,不能被忽略,这是混乱,我显然错过了一些东西。
  • 设置在项目上的clickListner在onBindViewHolder似乎也显著慢,比viewHolder类整行上添加clickListner不太敏感。

什么是设置你的媒体播放器,并与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(); 
       } 
      }); 
     } 
    }); 
} 
+0

你为什么要“聆听”媒体播放器?如果您需要对用户交互做出反应,为什么不添加两个监听器:onLongClick()和onClick()。 LongClick可以启动,当用户停止按下时,onClick()将自动调用,您可以停止播放。 – Gotiasits

+0

我并不需要停止播放,我使用的声音文件只有1-2秒长。 setOnCompleteListener是这样的,当文件完成播放时,它将释放所有资源,如果这就是你的意思。 – LuckyXII

回答

0

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

@LuckyXII有帮助吗? – Gotiasits

+0

对不起,它可能解决了以下问题:快速点击会尝试释放已释放的资源并抛出非法状态异常,但仅仅是因为longClick延迟允许该过程完成(我无法完全确定它是原因虽然)。 然而,由于音频文件只有1-2秒长,longClick等待时间太长,以至于感觉平滑并且不是问题的真正解决方案。 我确实找到了一种我认为可能会奏效的解决方案,但因为我是一个想出来的人,而且我是绝对的新手,所以我不能说这是否是“好”的做法 – LuckyXII

+0

那么,onLongClick应该立即执行播放声音。无论如何感谢您的反馈。祝你好运! – Gotiasits

0

OBS正如我回答我的问题,我不能说这是acctualy很好的做法,但它没有解决我遇到的问题,如果有人察觉错误或有更好的更有效然后请发表一个答案并详细说明。

  • 而不是在onBindViewHolder中声明MediaPlayer我使它成为一个类变量,这使我可以避免它最终并且能够在发布后使​​其无效。
  • 然后,我在onClick方法中定义它,以确保它永远不会为空,并且总是在需要时进行声明。
  • 我必须让我的持有者和“项目”最终以使用它们的onClick内但这似乎已经奏效(recyclerView魔法我猜)

的应用程序不再崩溃,onCompletionListener应清除所有资源,这是当前的代码:

//类变量和媒体播放器的方法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); 
      } 
     } 
    }); 
}