2017-09-04 68 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); 
      } 
     } 
    }); 
}