MediaController objects are thread-safe.
Topics covered here:
When a controller is created with the
SessionToken for a
(i.e. session token type is
SessionToken.TYPE_LIBRARY_SERVICE), the controller binds to the service for connecting
MediaSession in it.
MediaSessionService will provide a session to connect.
When a controller connects to a session,
will be called to either accept or reject the connection. Wait
MediaController.ControllerCallback.onConnected(MediaController, SessionCommandGroup) or
MediaController.ControllerCallback.onDisconnected(MediaController) for the result.
When the connected session is closed, the controller will receive
When you're done, use
close() to clean up resources. This also helps session service
to be destroyed when there's no controller associated with it.
Controlling the MediaSession in the same processWhen you control the
SessionPlayer, it's recommended to use them directly rather than creating
MediaController. However, if you need to use
MediaControllerin the same process, be careful not to block session callback executor's thread. Here's an example code that would never return due to the thread issue.
When a session gets a command from a controller, the session's
// Code runs on the main thread. MediaSession session = new MediaSession.Builder(context, player) .setSessionCallback(sessionCallback, Context.getMainExecutor(context)).build(); MediaController controller = new MediaController.Builder(context) .setSessionToken(session.getToken()) .setControllerCallback(Context.getMainExecutor(context), controllerCallback) .build(); // This will hang and never return. controller.play().get();
MediaSession.SessionCallback.onCommandRequest(MediaSession, MediaSession.ControllerInfo, SessionCommand)would be executed on the session's callback executor to decide whether to ignore or handle the incoming command. To do so, the session's callback executor shouldn't be blocked to handle the incoming calls. However, if you call
Future.get()on the thread for the session callback executor, then your call wouldn't be executed and never return.
To avoid such issue, don't block the session callback executor's thread. Creating a dedicated
thread for the session callback executor would be helpful. See
Executors.newSingleThreadExecutor() for creating a new thread.