在 RecyclerView 切换音频源时处理 MediaPlayer 时遇到问题
Having trouble with handling MediaPlayer in RecyclerView switching audio sources
我有一个 RecyclerView,它是一个乐器节拍列表,每个项目都包含一个乐器名称、制作人名称和从 Firebase 存储中检索到的音频源。当您单击播放按钮时,它会触发 OnClickListener 并将数据源设置为项目音乐的位置 link 并使用 OnPrepareListener 播放音频。我遇到的问题是,如果我单击另一个项目的播放按钮,它也会播放该音频,而我的 objective 是停止上一个音频并启动新音频。这是我的代码:
public void onBindViewHolder(@NonNull final TrackHolder holder, final int position) {
holder.mInstrumentalName.setText(tracks.get(position).getInstrumentalName());
holder.mProducer.setText(tracks.get(position).getProducer());
final MediaPlayer mediaPlayer = new MediaPlayer();
holder.mPlayButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
holder.mPlayButton.toggle();
try {
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(tracks.get(position).getMusicLink());
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
if (mediaPlayer.isPlaying()) {
Log.d("is_playing", "is_playing");
mediaPlayer.stop();
try {
mediaPlayer.setDataSource(tracks.get(position).getMusicLink());
} catch (IOException e) {
e.printStackTrace();
}
mediaPlayer.start();
} else {
mediaPlayer.start();
}
}
});
mediaPlayer.prepareAsync();
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
mediaPlayer.release();
Log.d("released", "released");
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
});
holder.setItemClickListener(new ItemClickListener() {
@Override
public void onItemClick(View v, int pos) {
Toast.makeText(context, Integer.toString(tracks.size()), Toast.LENGTH_SHORT).show();
}
});
}
下图为项目列表,黄色表示正在播放音乐,黑色表示未播放:
使用单个全局 MediaPlayer 而不是每个视图一个播放器。然后当你点击一个项目时,停止音频,设置一个新的数据源,然后重新启动。
无论如何,使用多个 MediaPlayer 通常不是一个好主意,这些东西会占用大量内存。因此,您当前的代码非常糟糕。在每次绑定时创建一个新的会浪费大量内存,并可能导致滚动缓慢。
我有一个 RecyclerView,它是一个乐器节拍列表,每个项目都包含一个乐器名称、制作人名称和从 Firebase 存储中检索到的音频源。当您单击播放按钮时,它会触发 OnClickListener 并将数据源设置为项目音乐的位置 link 并使用 OnPrepareListener 播放音频。我遇到的问题是,如果我单击另一个项目的播放按钮,它也会播放该音频,而我的 objective 是停止上一个音频并启动新音频。这是我的代码:
public void onBindViewHolder(@NonNull final TrackHolder holder, final int position) {
holder.mInstrumentalName.setText(tracks.get(position).getInstrumentalName());
holder.mProducer.setText(tracks.get(position).getProducer());
final MediaPlayer mediaPlayer = new MediaPlayer();
holder.mPlayButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
holder.mPlayButton.toggle();
try {
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(tracks.get(position).getMusicLink());
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
if (mediaPlayer.isPlaying()) {
Log.d("is_playing", "is_playing");
mediaPlayer.stop();
try {
mediaPlayer.setDataSource(tracks.get(position).getMusicLink());
} catch (IOException e) {
e.printStackTrace();
}
mediaPlayer.start();
} else {
mediaPlayer.start();
}
}
});
mediaPlayer.prepareAsync();
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
mediaPlayer.release();
Log.d("released", "released");
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
});
holder.setItemClickListener(new ItemClickListener() {
@Override
public void onItemClick(View v, int pos) {
Toast.makeText(context, Integer.toString(tracks.size()), Toast.LENGTH_SHORT).show();
}
});
}
下图为项目列表,黄色表示正在播放音乐,黑色表示未播放:
使用单个全局 MediaPlayer 而不是每个视图一个播放器。然后当你点击一个项目时,停止音频,设置一个新的数据源,然后重新启动。
无论如何,使用多个 MediaPlayer 通常不是一个好主意,这些东西会占用大量内存。因此,您当前的代码非常糟糕。在每次绑定时创建一个新的会浪费大量内存,并可能导致滚动缓慢。