You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:17:54