Search code examples
javaandroidexoplayer

Exoplayer throws player is accessed on the wrong thread Exception


when I use exoplayer I get a player is accessed on the wrong thread error. How can I solve this?

Non-fatal Exception: java.lang.IllegalStateException: Player is accessed on the wrong 
thread.
Current thread: 'main'
Expected thread: 'ConnectivityThread'
See https://exoplayer.dev/issues/player-accessed-on-wrong-thread

The player is started as a service via my BackgroundAudioService.class.

exoPlayer = new ExoPlayer.Builder(getApplicationContext()
            .build();

In the main thread my looper is running, the which updates the UI via exoplayer.getCurrentPosition().

public final Runnable updatePosition = new Runnable() {
    @Override
    public void run() {
        position  = BackgroundAudioService.getCurrentPostion();
    }
}

myHandler.postDelayed(updatePosition, myHandlerSleep);

I don't know how to solve this problem (which occurs just sometimes), please help.

Thanks Alejandro


Solution

  • I solved this by calling the status via a handler in the player's event listener. Starting a runnable from the listener which runs only when player.isPlaying() == true.

         player.addListener(new Player.Listener() {
            @Override
            public void onEvents(Player player, Player.Events events) {
                Player.Listener.super.onEvents(player, events);
    
                if (events.contains(Player.EVENT_IS_PLAYING_CHANGED)) {
                    if (player.isPlaying()) {
                        positionHandler.postDelayed(getCurrentPositionTask,CURRENT_POSITION_SLEEP);
    
                    } else {
                        positionHandler.removeCallbacks(getCurrentPositionTask);
    
                    }
                }
            }
        });
    
        public Runnable getCurrentPositionTask = new Runnable() {
    
        @Override
        public void run() {
            if (exoPlayer != null) {
                currentPostion = exoPlayer.getCurrentPosition();
                positionHandler.postDelayed(getCurrentPositionTask,CURRENT_POSITION_SLEEP);
            }            
        }
    };
    

    The UI calls the current position the same way in a runnable.

    I can't say whether this is the best way. but it's going well.

    GGK