Android RecyclerView中的音频播放器

Android RecyclerView中的音频播放器,android,android-recyclerview,android-mediaplayer,Android,Android Recyclerview,Android Mediaplayer,我试图在RecyclerView中实现音频(媒体播放器),但问题是它首先会崩溃,我曾尝试在bindView holder上实现代码,但它占用了所有资源,导致应用程序挂起和崩溃,我也曾尝试以另一种方式实现,但仍然会崩溃 我正在尝试制作一个类似whatsapp的聊天应用程序,但它的工作方式与我尝试的不同 public class AdapterNewSingleChat extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

我试图在RecyclerView中实现音频(媒体播放器),但问题是它首先会崩溃,我曾尝试在bindView holder上实现代码,但它占用了所有资源,导致应用程序挂起和崩溃,我也曾尝试以另一种方式实现,但仍然会崩溃

我正在尝试制作一个类似whatsapp的聊天应用程序,但它的工作方式与我尝试的不同

public class AdapterNewSingleChat extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    List<PojoNewChatMessage> data;
    SharedPreferences shdUSer;
    Context context;
    DatabaseReference userRef;
    private static final int MSG_UPDATE_SEEK_BAR = 1845;

    private MediaPlayer mediaPlayer;

    private Handler uiUpdateHandler;
    private int playingPosition;
    private SenderViewAudio playingHolder;

    public AdapterNewSingleChat(Context context) {
        this.context = context;
        shdUSer = context.getSharedPreferences("user", Context.MODE_PRIVATE);
        userRef = UserFirebase.databaseReference().child("User");
        this.playingPosition = -1;
    }

    public void setData(List<PojoNewChatMessage> data) {
        this.data = data;
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        if (i == R.layout.single_sent_message_text) {
            return new SenderViewMessage(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.single_sent_message_text, viewGroup, false));
        } else if (i == R.layout.single_received_message_text) {
            return new ReciverViewMessage(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.single_received_message_text, viewGroup, false));

        } else if (i == R.layout.single_sent_message_audio) {
            return new SenderViewAudio(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.single_sent_message_audio, viewGroup, false));

        }
        return null;
    }

    @Override
    public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder viewHolder, final int i) {
        if (viewHolder instanceof SenderViewMessage) {
            ((SenderViewMessage) viewHolder).txtSenderMessage.setText(data.get(i).getMessage());
            ((SenderViewMessage) viewHolder).txtSenderTime.setText(data.get(i).getTime());
        }
        if (viewHolder instanceof ReciverViewMessage) {
            ((ReciverViewMessage) viewHolder).txtReciverMessage.setText(data.get(i).getMessage());
            ((ReciverViewMessage) viewHolder).txtReciverTime.setText(data.get(i).getTime());

            userRef.child(data.get(i).getFrom()).addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                    if (dataSnapshot.exists()) {
                        String name = dataSnapshot.child("name").getValue().toString();
                        ((ReciverViewMessage) viewHolder).txtReciverName.setText(name);
                    }
                }

                @Override
                public void onCancelled(@NonNull DatabaseError databaseError) {

                }
            });

        }

        if (viewHolder instanceof SenderViewAudio){
            if (i == playingPosition) {
                playingHolder = ((SenderViewAudio)viewHolder);
                // this view holder corresponds to the currently playing audio cell
                // update its view to show playing progress
                updatePlayingView();
            } else {
                // and this one corresponds to non playing
                updateNonPlayingView(((SenderViewAudio)viewHolder));
            }
        }


    }

    @Override
    public int getItemCount() {
        return data.size();
    }

    @Override
    public int getItemViewType(int position) {
        if (data.get(position).getType().equals("txt")) {

            if (data.get(position).getFrom().equals(shdUSer.getString("user_id", ""))) {
                return R.layout.single_sent_message_text;
            } else {
                return R.layout.single_received_message_text;
            }
        }
        if (data.get(position).getType().equals("audio")) {
            if (data.get(position).getFrom().equals(shdUSer.getString("user_id", ""))) {
                return R.layout.single_sent_message_audio;
            } else {
                return R.layout.single_recieved_message_audio;
            }

        }
        return 0;
    }

    public class ReciverViewAudio extends RecyclerView.ViewHolder {
        TextView txtTime, txtName;
        ImageView imgPlay, imgPause;
        ProgressBar progressBar;

        public ReciverViewAudio(@NonNull View itemView) {
            super(itemView);
            txtTime = itemView.findViewById(R.id.txt_audio_reciver_text_time);
            imgPlay = itemView.findViewById(R.id.img_single_messeage_reciver_audio_play);
            imgPause = itemView.findViewById(R.id.img_single_messeage_reciver_audio_pause);
            progressBar = itemView.findViewById(R.id.progressbar_single_reciver_messeage_audio);
            txtName = itemView.findViewById(R.id.txt_reciver_text_name);
        }
    }

    public class SenderViewAudio extends RecyclerView.ViewHolder implements View.OnClickListener, SeekBar.OnSeekBarChangeListener {
        TextView txtTime;
        ImageView imgPlay, imgPause;
        SeekBar sbProgress;

        public SenderViewAudio(@NonNull View itemView) {
            super(itemView);
            txtTime = itemView.findViewById(R.id.txt_single_messeage_audio_time);
            imgPlay = itemView.findViewById(R.id.img_single_messeage_audio_play);
            imgPause = itemView.findViewById(R.id.img_single_messeage_audio_pause);
            sbProgress = itemView.findViewById(R.id.progressbar_single_messeage_audio);
            sbProgress.setOnSeekBarChangeListener(this);

        }

        @Override
        public void onClick(View v) {
            if (getAdapterPosition() == playingPosition) {
                // toggle between play/pause of audio
                if (mediaPlayer.isPlaying()) {
                    mediaPlayer.pause();
                } else {
                    mediaPlayer.start();
                }
            } else {
                // start another audio playback
                playingPosition = getAdapterPosition();
                if (mediaPlayer != null) {
                    if (null != playingHolder) {
                        updateNonPlayingView(playingHolder);
                    }
                    mediaPlayer.release();
                }
                playingHolder = this;
                startMediaPlayer(data.get(playingPosition).getMessage());
            }
            updatePlayingView();
        }

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            if (fromUser) {
                mediaPlayer.seekTo(progress);
            }
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {

        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {

        }
    }

    public class ReciverViewMessage extends RecyclerView.ViewHolder {
        TextView txtReciverMessage, txtReciverName, txtReciverTime;

        public ReciverViewMessage(@NonNull View itemView) {
            super(itemView);
            txtReciverMessage = itemView.findViewById(R.id.txt_reciver_text_message);
            txtReciverName = itemView.findViewById(R.id.txt_reciver_text_name);
            txtReciverTime = itemView.findViewById(R.id.txt_reciver_text_time);
        }
    }

    public class SenderViewMessage extends RecyclerView.ViewHolder {
        TextView txtSenderMessage, txtSenderTime;

        public SenderViewMessage(@NonNull View itemView) {
            super(itemView);
            txtSenderMessage = itemView.findViewById(R.id.txt_sender_text_message);
            txtSenderTime = itemView.findViewById(R.id.txt_sender_message_time);
        }
    }

    @Override
    public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) {
        super.onViewRecycled(holder);
        if (playingPosition == holder.getAdapterPosition()) {
            // view holder displaying playing audio cell is being recycled
            // change its state to non-playing
            if (playingHolder!=null)
            updateNonPlayingView(playingHolder);
            playingHolder = null;
        }
    }


    //==================AUDIO=======================

    private void updatePlayingView() {
        playingHolder.sbProgress.setMax(mediaPlayer.getDuration());
        playingHolder.sbProgress.setProgress(mediaPlayer.getCurrentPosition());
        playingHolder.sbProgress.setEnabled(true);
        if (mediaPlayer.isPlaying()) {
            uiUpdateHandler.sendEmptyMessageDelayed(MSG_UPDATE_SEEK_BAR, 100);
            playingHolder.imgPause.setVisibility(View.VISIBLE);
            playingHolder.imgPlay.setVisibility(View.GONE);
        } else {
            uiUpdateHandler.removeMessages(MSG_UPDATE_SEEK_BAR);
            playingHolder.imgPause.setVisibility(View.GONE);
            playingHolder.imgPlay.setVisibility(View.VISIBLE);
        }
    }

    private void updateNonPlayingView(SenderViewAudio holder) {
        if (holder == playingHolder) {
            uiUpdateHandler.removeMessages(MSG_UPDATE_SEEK_BAR);
        }
        holder.sbProgress.setEnabled(false);
        holder.sbProgress.setProgress(0);
        playingHolder.imgPause.setVisibility(View.GONE);
        playingHolder.imgPlay.setVisibility(View.VISIBLE);
    }

    private void startMediaPlayer(String audioResId) {
        mediaPlayer = new MediaPlayer();
        try {
            mediaPlayer.setDataSource(audioResId);
        } catch (IOException e) {
            e.printStackTrace();
        }
        mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                releaseMediaPlayer();
            }
        });
        mediaPlayer.start();
    }

    private void releaseMediaPlayer() {
        if (null != playingHolder) {
            updateNonPlayingView(playingHolder);
        }
        mediaPlayer.release();
        mediaPlayer = null;
        playingPosition = -1;
    }
}

不要把音乐放进回收站
在OnCutt事件

中使用一个接口来在活动或片段上做这个动作,如果你想在 CurryReVIEW < /C>中实现播放视频,那么你应该先考虑缓存视频然后播放它。这是避免MediaPlayer崩溃的方法。我该怎么做??如果可能,请提供简短的解决方案我必须对音频和视频文件执行此操作为什么不尝试使用谷歌的
ExoPlayer
,因为它具有缓存功能,不确定默认情况下是否启用,但如果不启用,则可以启用,它实际上是
MediasPlayer
的替代方案。是的,但自定义视图是问题,它对instagram类型的vide player有好处,我还在读这方面的文章
if (viewHolder instanceof SenderViewAudio) {
    ((SenderViewAudio) viewHolder).txtTime.setText(data.get(i).getTime());
    ((SenderViewAudio) viewHolder).imgPlay.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            try {
                player.setAudioStreamType(AudioManager.STREAM_MUSIC);
                player.setDataSource(context, Uri.parse(data.get(i).getMessage()));
                player.prepare();
                player.start();

            } catch (Exception e) {
                System.out.println(e.toString());
            }
            ((SenderViewAudio) viewHolder).imgPlay.setVisibility(View.GONE);
            ((SenderViewAudio) viewHolder).imgPause.setVisibility(View.VISIBLE);
        }
    });

    ((SenderViewAudio) viewHolder).imgPause.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            player.stop();
            player.release();
            ((SenderViewAudio) viewHolder).imgPlay.setVisibility(View.VISIBLE);
            ((SenderViewAudio) viewHolder).imgPause.setVisibility(View.GONE);
        }
    });
}