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

如何在ExoPlayer中创建线程持续监测播放位置?

实现ExoPlayer播放位置的持续监测

没问题,我来给你捋清楚怎么实现这个需求!要每隔1000ms记录ExoPlayer的播放位置,你之前用onIsPlayingChanged只触发一次的问题,核心是需要让监测任务循环执行,同时要配合播放状态启停任务,避免无效消耗。下面给你两种靠谱的实现方案:

方案一:Java环境下用Handler实现循环监测

这种方案适合你的Java代码场景,通过Handler让Runnable任务每隔1秒自我调度,形成持续监测:

1. 先定义全局的Handler和监测任务

在你的播放器所在的Activity/Fragment中,先声明Handler和Runnable:

private Handler playbackPositionHandler = new Handler(Looper.getMainLooper());
private Runnable positionPollingRunnable = new Runnable() {
    @Override
    public void run() {
        // 先判断播放器是否存在且正在播放,避免空指针
        if (player != null && player.isPlaying()) {
            long currentPosition = player.getCurrentPosition();
            Log.d(TAG, "Playing position is " + currentPosition);
            // 每隔1000ms再次执行当前任务,形成循环
            playbackPositionHandler.postDelayed(this, 1000);
        }
    }
};

2. 修改PlaybackStateListener的逻辑

在播放状态变化时,启动或停止监测任务:

private class PlaybackStateListener implements Player.EventListener{
    @Override
    public void onIsPlayingChanged(boolean isPlaying) {
        if(isPlaying){
            // 开始播放时立即启动第一次监测
            playbackPositionHandler.post(positionPollingRunnable);
        } else {
            // 停止播放时移除所有待执行的任务,避免后台继续跑
            playbackPositionHandler.removeCallbacks(positionPollingRunnable);
            Log.d(TAG, "Playback paused/stopped");
        }
    }
}

3. 别忘了清理资源(关键!)

在页面销毁时,一定要移除Handler的回调并释放播放器,防止内存泄漏:

@Override
protected void onDestroy() {
    super.onDestroy();
    playbackPositionHandler.removeCallbacks(positionPollingRunnable);
    if (player != null) {
        player.release();
        player = null;
    }
}

方案二:Kotlin环境下用协程实现(可选)

如果你的项目是Kotlin开发,用协程会更简洁,还能自动配合生命周期管理:

import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import androidx.lifecycle.lifecycleScope

private var positionPollingJob: Job? = null

private fun startPositionPolling() {
    positionPollingJob = lifecycleScope.launch {
        while (true) {
            player?.takeIf { it.isPlaying }?.let {
                val currentPosition = it.currentPosition
                Log.d(TAG, "Playing position is $currentPosition")
            }
            delay(1000)
        }
    }
}

private fun stopPositionPolling() {
    positionPollingJob?.cancel()
    positionPollingJob = null
}

// 播放状态监听
private val playbackStateListener = object : Player.EventListener {
    override fun onIsPlayingChanged(isPlaying: Boolean) {
        if (isPlaying) startPositionPolling() else stopPositionPolling()
    }
}

额外提醒

  • 不要直接用playbackPosition变量,最好调用player.getCurrentPosition()获取实时位置,避免变量更新不及时
  • 监测间隔设为1000ms是合理的,不要太频繁,否则会增加性能消耗

内容的提问来源于stack exchange,提问作者Nav89

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 14:17:31