Apps, die derzeit die eigenständige com.google.android.exoplayer2
-Bibliothek und androidx.media
verwenden, sollten zu androidx.media3
migrieren. Verwenden Sie das Migrationsskript, um Gradle-Build-Dateien, Java- und Kotlin-Quelldateien sowie XML-Layoutdateien von ExoPlayer 2.19.1
zu AndroidX Media3 1.1.1
zu migrieren.
Übersicht
Bevor Sie die Migration durchführen, sollten Sie sich die folgenden Abschnitte ansehen, um mehr über die Vorteile der neuen APIs, die zu migrierenden APIs und die Voraussetzungen zu erfahren, die das Projekt Ihrer App erfüllen muss.
Gründe für die Migration zu Jetpack Media3
- Es ist das neue Zuhause von ExoPlayer, während
com.google.android.exoplayer2
eingestellt wird. - Greifen Sie mit
MediaBrowser
/MediaController
auf die Player API über Komponenten/Prozesse hinweg zu. - Nutzen Sie die erweiterten Funktionen der
MediaSession
- undMediaController
-API. - Werben Sie mit detaillierter Zugriffssteuerung für die Wiedergabefunktionen.
- Vereinfachen Sie Ihre App, indem Sie
MediaSessionConnector
undPlayerNotificationManager
entfernen. - Abwärtskompatibel mit Media-Compat-Client-APIs
(
MediaBrowserCompat
/MediaControllerCompat
/MediaMetadataCompat
)
Media-APIs, die zu AndroidX Media3 migriert werden müssen
- ExoPlayer und seine Erweiterungen
Dazu gehören alle Module des alten ExoPlayer-Projekts mit Ausnahme des eingestellten Moduls mediasession. Apps oder Module, die von Paketen incom.google.android.exoplayer2
abhängen, können mit dem Migrationsskript migriert werden. - MediaSessionConnector (abhängig von den
androidx.media.*
-Paketen vonandroidx.media:media:1.4.3+
)
Entfernen SieMediaSessionConnector
und verwenden Sie stattdessenandroidx.media3.session.MediaSession
. - MediaBrowserServiceCompat (abhängig von den
androidx.media.*
-Paketen vonandroidx.media:media:1.4.3+
)
Unterklassen vonandroidx.media.MediaBrowserServiceCompat
zuandroidx.media3.session.MediaLibraryService
und Code mitMediaBrowserCompat.MediaItem
zuandroidx.media3.common.MediaItem
migrieren. - MediaBrowserCompat (abhängig von den
android.support.v4.media.*
-Paketen vonandroidx.media:media:1.4.3+
)
Migrieren Sie den Clientcode mitMediaBrowserCompat
oderMediaControllerCompat
, umandroidx.media3.session.MediaBrowser
mitandroidx.media3.common.MediaItem
zu verwenden.
Voraussetzungen
Prüfen, ob Ihr Projekt unter Quellcodeverwaltung steht
Achten Sie darauf, dass Sie Änderungen, die von skriptbasierten Migrationstools vorgenommen wurden, problemlos rückgängig machen können. Wenn Sie Ihr Projekt noch nicht in der Quellcodeverwaltung haben, ist jetzt ein guter Zeitpunkt, damit zu beginnen. Wenn Sie das aus irgendeinem Grund nicht tun möchten, erstellen Sie vor Beginn der Migration eine Sicherungskopie Ihres Projekts.
App aktualisieren
Wir empfehlen, Ihr Projekt auf die neueste Version der ExoPlayer-Bibliothek zu aktualisieren und alle Aufrufe eingestellter Methoden zu entfernen. Wenn Sie das Skript für die Migration verwenden möchten, muss die Version, auf die Sie aktualisieren, mit der Version übereinstimmen, die vom Skript verarbeitet wird.
Erhöhen Sie die compileSdkVersion Ihrer App auf mindestens 32.
Aktualisieren Sie Gradle und das Android Studio Gradle-Plug-in auf eine aktuelle Version, die mit den oben aktualisierten Abhängigkeiten funktioniert. Beispiel:
- Android-Gradle-Plug-in-Version: 7.1.0
- Gradle-Version: 7.4
Ersetzen Sie alle Platzhalter-Importanweisungen, die ein Sternchen (*) verwenden, durch vollqualifizierte Importanweisungen: Löschen Sie die Platzhalter-Importanweisungen und verwenden Sie Android Studio, um die vollqualifizierten Anweisungen zu importieren (F2 – Alt/Eingabetaste, F2 – Alt/Eingabetaste usw.).
Von
com.google.android.exoplayer2.PlayerView
zucom.google.android.exoplayer2.StyledPlayerView
migrieren Das ist erforderlich, da es in AndroidX Media3 kein Äquivalent zucom.google.android.exoplayer2.PlayerView
gibt.
ExoPlayer mit Skriptunterstützung migrieren
Das Skript erleichtert die Migration von com.google.android.exoplayer2
zur neuen Paket- und Modulstruktur unter androidx.media3
. Das Skript führt einige Validierungsprüfungen für Ihr Projekt durch und gibt Warnungen aus, wenn die Validierung fehlschlägt.
Andernfalls werden die Zuordnungen umbenannter Klassen und Pakete in den Ressourcen eines in Java oder Kotlin geschriebenen Android-Gradle-Projekts angewendet.
usage: ./media3-migration.sh [-p|-c|-d|-v]|[-m|-l [-x <path>] [-f] PROJECT_ROOT]
PROJECT_ROOT: path to your project root (location of 'gradlew')
-p: list package mappings and then exit
-c: list class mappings (precedence over package mappings) and then exit
-d: list dependency mappings and then exit
-l: list files that will be considered for rewrite and then exit
-x: exclude the path from the list of file to be changed: 'app/src/test'
-m: migrate packages, classes and dependencies to AndroidX Media3
-f: force the action even when validation fails
-v: print the exoplayer2/media3 version strings of this script
-h, --help: show this help text
Migrationsskript verwenden
Laden Sie das Migrationsskript aus dem Tag des ExoPlayer-Projekts auf GitHub herunter, das der Version entspricht, auf die Sie Ihre App aktualisiert haben:
curl -o media3-migration.sh \ "https://raw.githubusercontent.com/google/ExoPlayer/r2.19.1/media3-migration.sh"
Machen Sie das Skript ausführbar:
chmod 744 media3-migration.sh
Führen Sie das Skript mit
--help
aus, um mehr über die Optionen zu erfahren.Führen Sie das Skript mit
-l
aus, um die für die Migration ausgewählten Dateien aufzulisten (verwenden Sie-f
, um die Auflistung ohne Warnungen zu erzwingen):./media3-migration.sh -l -f /path/to/gradle/project/root
Führen Sie das Skript mit
-m
aus, um Pakete, Klassen und Module Media3 zuzuordnen. Wenn Sie das Skript mit der Option-m
ausführen, werden Änderungen auf die ausgewählten Dateien angewendet.- Bei Validierungsfehler anhalten, ohne Änderungen vorzunehmen
./media3-migration.sh -m /path/to/gradle/project/root
- Erzwungene Ausführung
Wenn das Skript einen Verstoß gegen die Voraussetzungen findet, kann die Migration mit dem Flag
-f
erzwungen werden:./media3-migration.sh -m -f /path/to/gradle/project/root
# list files selected for migration when excluding paths
./media3-migration.sh -l -x "app/src/test/" -x "service/" /path/to/project/root
# migrate the selected files
./media3-migration.sh -m -x "app/src/test/" -x "service/" /path/to/project/root
Führen Sie diese manuellen Schritte aus, nachdem Sie das Skript mit der Option -m
ausgeführt haben:
- Prüfen Sie, wie das Skript Ihren Code geändert hat: Verwenden Sie ein Diff-Tool und beheben Sie potenzielle Probleme. Wenn Sie der Meinung sind, dass das Skript ein allgemeines Problem hat, das ohne Übergabe der Option
-f
eingeführt wurde, melden Sie einen Fehler. - Projekt erstellen: Verwenden Sie entweder
./gradlew clean build
oder wählen Sie in Android Studio File > Sync Project with Gradle Files (Datei > Projekt mit Gradle-Dateien synchronisieren) aus, dann Build > Clean project (Erstellen > Projekt bereinigen) und dann Build > Rebuild project (Erstellen > Projekt neu erstellen). Beobachten Sie den Build auf dem Tab Build – Build Output (Build – Build-Ausgabe) von Android Studio.
Empfohlene Folgeschritte:
- Beheben Sie Fehler bezüglich der Verwendung instabiler APIs.
- Verworfene API-Aufrufe ersetzen: Verwenden Sie die vorgeschlagene Ersatz-API. Bewegen Sie den Mauszeiger in Android Studio auf die Warnung und sehen Sie in der JavaDoc des eingestellten Symbols nach, was Sie stattdessen verwenden können.
- Importanweisungen sortieren: Öffnen Sie das Projekt in Android Studio, klicken Sie dann im Projektviewer mit der rechten Maustaste auf einen Paketordnerknoten und wählen Sie für die Pakete, die die geänderten Quelldateien enthalten, Importe optimieren aus.
Ersetzen Sie MediaSessionConnector
durch androidx.media3.session.MediaSession
.
Im alten MediaSessionCompat
war das MediaSessionConnector
für die Synchronisierung des Status des Players mit dem Status der Sitzung und für den Empfang von Befehlen von Controllern verantwortlich, die an die entsprechenden Player-Methoden delegiert werden mussten. Mit AndroidX Media3 erfolgt dies direkt über die MediaSession
, ohne dass ein Connector erforderlich ist.
Alle Verweise auf MediaSessionConnector entfernen:Wenn Sie das automatisierte Skript zum Migrieren von ExoPlayer-Klassen und -Paketen verwendet haben, ist Ihr Code wahrscheinlich in einem nicht kompilierbaren Zustand, was die
MediaSessionConnector
betrifft, die nicht aufgelöst werden kann. Android Studio zeigt Ihnen den fehlerhaften Code an, wenn Sie versuchen, die App zu erstellen oder zu starten.Fügen Sie in der Datei
build.gradle
, in der Sie Ihre Abhängigkeiten verwalten, eine Implementierungsabhängigkeit zum AndroidX Media3-Sitzungsmodul hinzu und entfernen Sie die alte Abhängigkeit:implementation "androidx.media3:media3-session:1.7.1"
Ersetzen Sie
MediaSessionCompat
durchandroidx.media3.session.MediaSession
.Verwenden Sie an der Codestelle, an der Sie die Legacy-
MediaSessionCompat
erstellt haben,androidx.media3.session.MediaSession.Builder
, um eineMediaSession
zu erstellen. Übergeben Sie den Player, um den Sitzungs-Builder zu erstellen.val player = ExoPlayer.Builder(context).build() mediaSession = MediaSession.Builder(context, player) .setSessionCallback(MySessionCallback()) .build()
Implementieren Sie
MySessionCallback
nach Bedarf in Ihrer App. Dies ist optional. Wenn du Controllern erlauben möchtest, dem Player Media-Elemente hinzuzufügen, implementiereMediaSession.Callback.onAddMediaItems()
. Sie stellt verschiedene aktuelle und Legacy-API-Methoden bereit, mit denen Media-Elemente auf abwärtskompatible Weise zur Wiedergabe im Player hinzugefügt werden. Dazu gehören dieMediaController.set/addMediaItems()
-Methoden des Media3-Controllers sowie dieTransportControls.prepareFrom*/playFrom*
-Methoden der Legacy-API. Eine Beispielimplementierung vononAddMediaItems
finden Sie imPlaybackService
der Demo-App für die Sitzung.Geben Sie die Mediensitzung an der Codestelle frei, an der Sie die Sitzung vor der Migration beendet haben:
mediaSession?.run { player.release() release() mediaSession = null }
MediaSessionConnector
-Funktionen in Media3
In der folgenden Tabelle sind die Media3-APIs aufgeführt, die Funktionen übernehmen, die zuvor in MediaSessionConnector
implementiert wurden.
MediaSessionConnector | AndroidX Media3 |
---|---|
CustomActionProvider |
MediaSession.Callback.onCustomCommand()/
MediaSession.setMediaButtonPreferences() |
PlaybackPreparer |
MediaSession.Callback.onAddMediaItems()
(prepare() wird intern aufgerufen)
|
QueueNavigator |
ForwardingSimpleBasePlayer |
QueueEditor |
MediaSession.Callback.onAddMediaItems() |
RatingCallback |
MediaSession.Callback.onSetRating() |
PlayerNotificationManager |
DefaultMediaNotificationProvider/
MediaNotification.Provider |
MediaBrowserService
zu MediaLibraryService
migrieren
Mit AndroidX Media3 wird MediaLibraryService
eingeführt, das MediaBrowserServiceCompat
ersetzt. Die JavaDoc von MediaLibraryService
und der zugehörigen Superklasse MediaSessionService
bieten eine gute Einführung in die API und das asynchrone Programmiermodell des Dienstes.
Die MediaLibraryService
ist abwärtskompatibel mit der MediaBrowserService
. Eine Client-App, die MediaBrowserCompat
oder MediaControllerCompat
verwendet, funktioniert weiterhin ohne Codeänderungen, wenn sie eine Verbindung zu einem MediaLibraryService
herstellt. Für einen Kunden ist transparent, ob Ihre App eine MediaLibraryService
oder eine Legacy-MediaBrowserServiceCompat
verwendet.

Damit die Abwärtskompatibilität funktioniert, müssen Sie beide Dienstschnittstellen mit Ihrem Dienst im
AndroidManifest.xml
registrieren. So findet ein Client Ihren Dienst über die erforderliche Dienstschnittstelle:<service android:name=".MusicService" android:exported="true"> <intent-filter> <action android:name="androidx.media3.session.MediaLibraryService"/> <action android:name="android.media.browse.MediaBrowserService" /> </intent-filter> </service>
Fügen Sie in der Datei
build.gradle
, in der Sie Ihre Abhängigkeiten verwalten, eine Implementierungsabhängigkeit für das AndroidX Media3-Sitzungsmodul hinzu und entfernen Sie die alte Abhängigkeit:implementation "androidx.media3:media3-session:1.7.1"
Dienst so ändern, dass er von
MediaLibraryService
anstelle vonMediaBrowserService
erbtMediaBrowserService
Wie bereits erwähnt, istMediaLibraryService
mit dem altenMediaBrowserService
kompatibel. Die API, die der Dienst Clients anbietet, bleibt also unverändert. Es ist also wahrscheinlich, dass eine App den Großteil der Logik beibehalten kann, die für die Implementierung vonMediaBrowserService
erforderlich ist, und sie für die neueMediaLibraryService
anpassen kann.Die wichtigsten Unterschiede im Vergleich zum alten
MediaBrowserServiceCompat
sind:Methoden für den Dienstlebenszyklus implementieren:Die Methoden, die für den Dienst selbst überschrieben werden müssen, sind
onCreate/onDestroy
. Hier weist eine App die Bibliothekssitzung, den Player und andere Ressourcen zu bzw. gibt sie frei. Zusätzlich zu den Standardmethoden für den Lebenszyklus von Diensten muss eine ApponGetSession(MediaSession.ControllerInfo)
überschreiben, um dasMediaLibrarySession
zurückzugeben, das inonCreate
erstellt wurde.MediaLibraryService.MediaLibrarySessionCallback implementieren:Zum Erstellen einer Sitzung ist ein
MediaLibraryService.MediaLibrarySessionCallback
erforderlich, in dem die tatsächlichen Domain-API-Methoden implementiert werden. Anstatt API-Methoden des alten Dienstes zu überschreiben, überschreiben Sie die Methoden vonMediaLibrarySession.Callback
.Der Callback wird dann zum Erstellen von
MediaLibrarySession
verwendet:mediaLibrarySession = MediaLibrarySession.Builder(this, player, MySessionCallback()) .build()
Die vollständige API von MediaLibrarySessionCallback finden Sie in der API-Dokumentation.
MediaSession.Callback.onAddMediaItems()
implementieren: Der CallbackonAddMediaItems(MediaSession, ControllerInfo, List<MediaItem>)
stellt verschiedene aktuelle und Legacy-API-Methoden bereit, mit denen Media-Elemente auf abwärtskompatible Weise für die Wiedergabe im Player hinzugefügt werden. Dazu gehören dieMediaController.set/addMediaItems()
-Methoden des Media3-Controllers sowie dieTransportControls.prepareFrom*/playFrom*
-Methoden der Legacy-API. Eine Beispielimplementierung des Callbacks finden Sie imPlaybackService
der Demo-App für die Sitzung.AndroidX Media3 verwendet stattdessen
androidx.media3.common.MediaItem
anstelle von MediaBrowserCompat.MediaItem und MediaMetadataCompat. Teile Ihres Codes, die mit den alten Klassen verknüpft sind, müssen entsprechend geändert oder der Media3-MediaItem
zugeordnet werden.Das allgemeine asynchrone Programmiermodell wurde in
Futures
geändert, im Gegensatz zum trennbarenResult
-Ansatz vonMediaBrowserServiceCompat
. Ihre Dienstimplementierung kann anstelle des Trennens eines Ergebnisses ein asynchronesListenableFuture
zurückgeben oder ein sofortiges Future zurückgeben, um einen Wert direkt zurückzugeben.
PlayerNotificationManager entfernen
Das MediaLibraryService
unterstützt automatisch Medienbenachrichtigungen und das PlayerNotificationManager
kann entfernt werden, wenn ein MediaLibraryService
oder MediaSessionService
verwendet wird.
Eine App kann die Benachrichtigung anpassen, indem sie in onCreate()
einen benutzerdefinierten MediaNotification.Provider
festlegt, der DefaultMediaNotificationProvider
ersetzt. Das MediaLibraryService
sorgt dann dafür, dass der Dienst wie erforderlich im Vordergrund gestartet wird.
Durch Überschreiben von MediaLibraryService.updateNotification()
kann eine App die vollständige Verantwortung für das Posten einer Benachrichtigung und das Starten/Beenden des Dienstes im Vordergrund übernehmen.
Clientcode mit einem MediaBrowser migrieren
Mit AndroidX Media3 implementiert ein MediaBrowser
die MediaController/Player
-Schnittstellen und kann neben dem Durchsuchen der Mediathek auch zur Steuerung der Medienwiedergabe verwendet werden. Wenn Sie in der alten Welt ein MediaBrowserCompat
und ein MediaControllerCompat
erstellen mussten, können Sie dasselbe tun, indem Sie nur das MediaBrowser
in Media3 verwenden.
Eine MediaBrowser
kann erstellt werden und darauf warten, dass die Verbindung zum Dienst hergestellt wird:
scope.launch {
val sessionToken =
SessionToken(context, ComponentName(context, MusicService::class.java)
browser =
MediaBrowser.Builder(context, sessionToken))
.setListener(BrowserListener())
.buildAsync()
.await()
// Get the library root to start browsing the library.
root = browser.getLibraryRoot(/* params= */ null).await();
// Add a MediaController.Listener to listen to player state events.
browser.addListener(playerListener)
playerView.setPlayer(browser)
}
Unter Wiedergabe in der Mediensitzung steuern erfährst du, wie du einen MediaController
zum Steuern der Wiedergabe im Hintergrund erstellst.
Weitere Schritte und Bereinigung
Instabile API-Fehler
Nach der Migration zu Media3 werden möglicherweise Lint-Fehler bezüglich instabiler API-Verwendungen angezeigt.
Diese APIs sind sicher zu verwenden und die Lint-Fehler sind ein Nebenprodukt unserer neuen binären Kompatibilitätsgarantien. Wenn Sie keine strenge binäre Kompatibilität benötigen, können diese Fehler mit der Annotation @OptIn
unterdrückt werden.
Hintergrund
Weder ExoPlayer v1 noch v2 boten strenge Garantien für die binäre Kompatibilität der Bibliothek zwischen aufeinanderfolgenden Versionen. Die ExoPlayer API ist bewusst sehr umfangreich, damit Apps fast jeden Aspekt der Wiedergabe anpassen können. In nachfolgenden Versionen von ExoPlayer wurden gelegentlich Symbole umbenannt oder andere wichtige Änderungen vorgenommen (z.B. neue erforderliche Methoden für Schnittstellen). In den meisten Fällen wurden diese Probleme dadurch behoben, dass das neue Symbol zusammen mit dem alten Symbol für einige Versionen eingeführt wurde, damit Entwickler Zeit hatten, ihre Verwendungen zu migrieren. Das war jedoch nicht immer möglich.
Diese schwerwiegenden Änderungen führten zu zwei Problemen für Nutzer der ExoPlayer-Bibliotheken v1 und v2:
- Ein Upgrade auf die ExoPlayer-Version kann dazu führen, dass der Code nicht mehr kompiliert wird.
- Bei einer App, die sowohl direkt als auch über eine Zwischenbibliothek von ExoPlayer abhängig war, musste darauf geachtet werden, dass beide Abhängigkeiten dieselbe Version hatten. Andernfalls konnten binäre Inkompatibilitäten zu Laufzeitabstürzen führen.
Verbesserungen in Media3
Media3 garantiert die binäre Kompatibilität für einen Teil der API-Oberfläche. Die Teile, die keine binäre Kompatibilität garantieren, sind mit @UnstableApi
gekennzeichnet. Um diesen Unterschied deutlich zu machen, wird bei der Verwendung instabiler API-Symbole ein Lint-Fehler generiert, sofern sie nicht mit @OptIn
annotiert sind.
Nach der Migration von ExoPlayer v2 zu Media3 werden möglicherweise viele instabile API-Lint-Fehler angezeigt. Dadurch kann es so aussehen, als wäre Media3 „weniger stabil“ als ExoPlayer v2. Das ist nicht der Fall. Die „instabilen“ Teile der Media3 API haben denselben Stabilitätsgrad wie die gesamte ExoPlayer v2 API-Oberfläche. Die Garantien der stabilen Media3 API-Oberfläche sind in ExoPlayer v2 überhaupt nicht verfügbar. Der Unterschied besteht lediglich darin, dass Sie jetzt durch einen Lint-Fehler auf die verschiedenen Stabilitätsstufen aufmerksam gemacht werden.
Instabile API-Lint-Fehler beheben
Im Abschnitt zur Fehlerbehebung für diese Lint-Fehler finden Sie Informationen dazu, wie Sie Java- und Kotlin-Verwendungen instabiler APIs mit @OptIn
annotieren.
Eingestellte APIs
Aufrufe von verworfenen APIs werden in Android Studio durchgestrichen dargestellt. Wir empfehlen, solche Aufrufe durch die entsprechende Alternative zu ersetzen. Bewegen Sie den Mauszeiger auf das Symbol, um die JavaDoc-Informationen zu sehen, in denen die alternative API angegeben ist.

Codebeispiele und Demo-Apps
- Demo-App für die AndroidX Media3-Sitzung (Mobilgeräte und WearOS)
- Benutzerdefinierte Aktionen
- System-UI-Benachrichtigung, MediaButton/BT
- Wiedergabesteuerung mit Google Assistant
- UAMP: Android Media Player (Branch „media3“) (Mobilgeräte, AutomotiveOS)
- System-UI-Benachrichtigung, MediaButton/BT, Fortsetzung der Wiedergabe
- Wiedergabesteuerung mit Google Assistant/Wear OS
- AutomotiveOS: Benutzerdefinierter Befehl und Anmeldung