ExoPlayer多视频播放异常:Firebase ListAdapter点击问题排查
解决Firebase ListAdapter点击第二个视频无法播放的问题
看起来你遇到的问题大概率是视频ID传递错误或者ExoPlayer实例没有正确重置/重新初始化导致的,下面是具体的排查和解决方法:
1. 确认列表点击时传递的是当前项的正确视频ID
首先要确保在列表项点击事件中,你获取的是当前点击位置对应的视频ID,而不是复用了全局变量或者旧值:
// 在Firebase ListAdapter的onBindViewHolder方法中设置点击事件 @Override protected void onBindViewHolder(@NonNull YourViewHolder holder, int position, @NonNull YourModel model) { // 绑定其他数据... holder.itemView.setOnClickListener(v -> { // 直接从当前绑定的model中获取视频ID,不要用全局的mWineVideoID之类的变量 String currentVideoId = model.getTastingWineVideoId(); Intent playIntent = new Intent(v.getContext(), VideoPlayerActivity.class); playIntent.putExtra("SELECTED_VIDEO_ID", currentVideoId); v.getContext().startActivity(playIntent); }); }
这里要注意:避免使用全局的mWineVideoID或tastingWineVideoId来传递数据,因为这些变量可能会被后续的列表项绑定覆盖,导致点击第二个项时传递的还是第一个项的ID(或者错误的旧值)。
2. 确保播放Activity每次都重新初始化播放器并加载新的视频源
如果你的播放Activity复用了ExoPlayer实例(比如把播放器定义为全局变量),第二次进入时可能没有替换新的视频源,导致播放的还是之前的内容(或者因为源为空无法播放)。正确的做法是:
- 在
onCreate或onResume中,每次都从Intent中获取新的视频ID,重新创建MediaSource并初始化播放器 - 在
onDestroy中释放播放器资源,避免泄漏
示例代码:
public class VideoPlayerActivity extends AppCompatActivity { private SimpleExoPlayer player; private PlayerView playerView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_video_player); playerView = findViewById(R.id.player_view); // 获取传递的视频ID,必须每次都重新获取 String videoId = getIntent().getStringExtra("SELECTED_VIDEO_ID"); if (TextUtils.isEmpty(videoId)) { // 没有有效视频ID,直接结束Activity finish(); return; } // 初始化ExoPlayer实例 player = new SimpleExoPlayer.Builder(this).build(); playerView.setPlayer(player); // 根据视频ID构建视频源(这里替换成你获取视频URL的逻辑) DataSource.Factory dataSourceFactory = new DefaultHttpDataSource.Factory(); MediaItem mediaItem = MediaItem.fromUri(getVideoUrlByVideoId(videoId)); MediaSource mediaSource = new ProgressiveMediaSource.Factory(dataSourceFactory) .createMediaSource(mediaItem); // 设置并准备播放 player.setMediaSource(mediaSource); player.prepare(); player.play(); // 监听播放完成,自动返回列表 player.addListener(new Player.Listener() { @Override public void onPlaybackStateChanged(int playbackState) { if (playbackState == Player.STATE_ENDED) { finish(); } } }); } // 根据视频ID获取对应的视频URL(替换成你的实际逻辑) private Uri getVideoUrlByVideoId(String videoId) { // 比如从Firebase Storage获取URL,或者拼接固定地址 return Uri.parse("https://your-video-host.com/" + videoId + ".mp4"); } @Override protected void onDestroy() { super.onDestroy(); // 必须释放播放器资源,避免内存泄漏和资源占用 if (player != null) { player.release(); player = null; } } }
3. 检查字段命名是否混淆
你代码里出现了mTastingWineID/tastingWineId、mWineVideoID/tastingWineVideoId这些相似的字段,要确保:
- 你的数据模型类中,字段名和Firebase数据库中的字段名完全匹配(或者用
@PropertyName注解映射) - 在获取视频ID时,没有错误地使用了其他字段(比如把
tastingWineId当成了视频ID)
4. 排查Firebase ListAdapter的数据源是否正确
确保Firebase ListAdapter的数据源是实时更新的,并且getItem(position)返回的是对应位置的正确模型数据。可以在onBindViewHolder中打印日志,确认每个位置的视频ID是否正确:
Log.d("VideoList", "Position " + position + " video ID: " + model.getTastingWineVideoId());
如果日志显示第二个位置的视频ID为空或错误,那就要检查Firebase数据库中的数据是否正确,或者模型类的字段映射是否有问题。
内容的提问来源于stack exchange,提问作者Andrew
相关产品推荐
相关产品推荐

