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
Lesen Sie sich vor der Migration die folgenden Abschnitte durch, um mehr über die Vorteile der neuen APIs, die zu migrierenden APIs und die Voraussetzungen zu erfahren, die das Projekt Ihrer App erfüllen sollte.
Warum zu Jetpack Media3 migrieren?
- Es ist das neue Zuhause von ExoPlayer, während
com.google.android.exoplayer2eingestellt wird. - Zugriff auf die Player API über Komponenten/Prozesse hinweg mit
MediaBrowser/MediaController. - Verwenden Sie die erweiterten Funktionen der
MediaSession- undMediaController-API. - Wiedergabefunktionen mit detaillierter Zugriffssteuerung bewerben.
- Vereinfachen Sie Ihre App, indem Sie
MediaSessionConnectorundPlayerNotificationManagerentfernen. - Abwärtskompatibel mit media-compat-Client-APIs (
MediaBrowserCompat/MediaControllerCompat/MediaMetadataCompat)
Media APIs zur Migration zu AndroidX Media3
- ExoPlayer und seine Erweiterungen
Dazu gehören alle Module des alten ExoPlayer-Projekts mit Ausnahme des Moduls mediasession, das eingestellt wurde. Apps oder Module, die von Paketen incom.google.android.exoplayer2abhängen, können mit dem Migrationsskript migriert werden. - MediaSessionConnector (abhängig von den
androidx.media.*-Paketen vonandroidx.media:media:1.4.3+)
Entferne denMediaSessionConnectorund verwende stattdessen denandroidx.media3.session.MediaSession. - MediaBrowserServiceCompat (abhängig von den
androidx.media.*-Paketen vonandroidx.media:media:1.4.3+)
Migriere Unterklassen vonandroidx.media.MediaBrowserServiceCompatzuandroidx.media3.session.MediaLibraryServiceund Code, derMediaBrowserCompat.MediaItemverwendet, zuandroidx.media3.common.MediaItem. - MediaBrowserCompat (abhängig von den
android.support.v4.media.*-Paketen vonandroidx.media:media:1.4.3+)
Migriere den Clientcode mitMediaBrowserCompatoderMediaControllerCompat, umandroidx.media3.session.MediaBrowsermitandroidx.media3.common.MediaItemzu verwenden.
Vorbereitung
Projekt unter Quellcodeverwaltung stellen
Sorgen Sie dafür, dass Sie Änderungen, die durch skriptbasierte Migrationstools vorgenommen wurden, einfach rückgängig machen können. Wenn Sie Ihr Projekt noch nicht unter Versionsverwaltung haben, ist jetzt ein guter Zeitpunkt, damit zu beginnen. Wenn Sie das aus irgendeinem Grund nicht tun möchten, erstellen Sie eine Sicherungskopie Ihres Projekts, bevor Sie mit der Migration beginnen.
App aktualisieren
Wir empfehlen, Ihr Projekt auf die neueste Version der ExoPlayer-Bibliothek zu aktualisieren und alle Aufrufe von verworfenen Methoden zu entfernen. Wenn Sie das Skript für die Migration verwenden möchten, müssen Sie die Version, auf die Sie aktualisieren, mit der vom Skript verarbeiteten Version abgleichen.
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 genannten aktualisierten Abhängigkeiten funktioniert. Beispiel:
- Android-Gradle-Plug-in-Version: 7.1.0
- Gradle-Version: 7.4
Ersetzen Sie alle Importanweisungen mit Platzhaltern, die ein Sternchen (*) verwenden, und verwenden Sie vollständig qualifizierte Importanweisungen: Löschen Sie die Importanweisungen mit Platzhaltern und verwenden Sie Android Studio, um die vollständig qualifizierten Anweisungen zu importieren (F2 – Alt/Eingabe, F2 – Alt/Eingabe, ...).
Von
com.google.android.exoplayer2.PlayerViewzucom.google.android.exoplayer2.StyledPlayerViewmigrieren. Das ist erforderlich, weil es in AndroidX Media3 kein Äquivalent zucom.google.android.exoplayer2.PlayerViewgibt.
ExoPlayer mit Scriptunterstützung migrieren
Das Script erleichtert den Wechsel von com.google.android.exoplayer2 zur neuen Paket- und Modulstruktur unter androidx.media3. Das Script 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 Android-Gradle-Projekts angewendet, das in Java oder Kotlin geschrieben wurde.
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.shFühren Sie das Skript mit
--helpaus, um mehr über die Optionen zu erfahren.Führen Sie das Skript mit
-laus, 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/rootFühre das Script mit
-maus, um Pakete, Klassen und Module Media3 zuzuordnen. Wenn Sie das Script mit der Option-mausführen, werden die Ä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 Script einen Verstoß gegen die Voraussetzungen findet, kann die Migration mit dem Flag
-ferzwungen 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 die folgenden 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 die Option
-feingeführt wurde, sollten Sie einen Fehler melden. - Projekt erstellen: Verwenden Sie entweder
./gradlew clean buildoder wählen Sie in Android Studio Datei > Projekt mit Gradle-Dateien synchronisieren, dann Build > Projekt bereinigen und dann Build > Projekt neu erstellen aus. Sie können den Build auf dem Tab Build – Build-Ausgabe in Android Studio im Blick behalten.
Empfohlene Folgeschritte:
- Beheben Sie Fehler bei 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 rufen Sie die JavaDoc des verworfenen Symbols auf, um herauszufinden, was Sie stattdessen verwenden sollten.
- Importanweisungen sortieren: Öffnen Sie das Projekt in Android Studio, klicken Sie im Projekt-Viewer mit der rechten Maustaste auf einen Paketordnerknoten und wählen Sie für die Pakete, die die geänderten Quelldateien enthalten, Optimize imports aus.
MediaSessionConnector durch androidx.media3.session.MediaSession ersetzen
In der alten MediaSessionCompat-Welt war der MediaSessionConnector dafür verantwortlich, den Status des Players mit dem Status der Sitzung zu synchronisieren und Befehle von Controllern zu empfangen, die an entsprechende Player-Methoden delegiert werden mussten. Mit AndroidX Media3 wird dies direkt von MediaSession erledigt, ohne dass ein Connector erforderlich ist.
Alle Verweise auf und die Verwendung von MediaSessionConnector entfernen:Wenn Sie das automatisierte Skript zum Migrieren von ExoPlayer-Klassen und -Paketen verwendet haben, hat das Skript Ihren Code wahrscheinlich in einem nicht kompilierbaren Zustand in Bezug auf die
MediaSessionConnectorhinterlassen, die nicht aufgelöst werden können. In Android Studio wird der fehlerhafte Code angezeigt, 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.11.1"Ersetzen Sie
MediaSessionCompatdurchandroidx.media3.session.MediaSession.Verwenden Sie am Code-Standort, an dem Sie die Legacy-
MediaSessionCompaterstellt haben,androidx.media3.session.MediaSession.Builder, um eineMediaSessionzu erstellen. Übergeben Sie den Player, um den Session Builder zu erstellen.Kotlin
val player = ExoPlayer.Builder(context).build() mediaSession = MediaSession.Builder(context, player).setCallback(MySessionCallback()).build()
Java
ExoPlayer player = new ExoPlayer.Builder(context).build(); mediaSession = new MediaSession.Builder(context, player).setCallback(new MySessionCallback()).build();
Implementieren Sie
MySessionCallback, wie es für Ihre App erforderlich ist. Dies ist optional. Wenn du Controllern erlauben möchtest, dem Player Mediendateien hinzuzufügen, implementiereMediaSession.Callback.onAddMediaItems(). Sie stellt verschiedene aktuelle und ältere API-Methoden bereit, mit denen Mediendateien abwärtskompatibel zur Wiedergabe im Player hinzugefügt werden können. Dazu gehören dieMediaController.set/addMediaItems()-Methoden des Media3-Controllers sowie dieTransportControls.prepareFrom*/playFrom*-Methoden der Legacy API. Eine Beispielimplementierung vononAddMediaItemsfinden Sie in derPlaybackServiceder Session-Demo-App.Gib die Mediensitzung an der Codestelle frei, an der du die Sitzung vor der Migration gelöscht hast:
Kotlin
mediaSession?.run { player.release() release() mediaSession = null }
Java
if (mediaSession != null) { mediaSession.getPlayer().release(); mediaSession.release(); mediaSession = null; }
MediaSessionConnector-Funktionen in Media3
In der folgenden Tabelle sind die Media3 APIs aufgeführt, die Funktionen verarbeiten, 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
AndroidX Media3 führt MediaLibraryService ein, das MediaBrowserServiceCompat ersetzt. Das JavaDoc von MediaLibraryService und seiner übergeordneten Klasse MediaSessionService bietet eine gute Einführung in die API und das asynchrone Programmiermodell des Dienstes.
MediaLibraryService ist abwärtskompatibel mit MediaBrowserService. Eine Clientanwendung, die MediaBrowserCompat oder MediaControllerCompat verwendet, funktioniert weiterhin ohne Codeänderungen, wenn eine Verbindung zu einem MediaLibraryService hergestellt wird. Für einen Client ist es transparent, ob Ihre Anwendung eine MediaLibraryService oder eine Legacy-MediaBrowserServiceCompat verwendet.
Damit die Abwärtskompatibilität funktioniert, müssen Sie beide Dienstschnittstellen mit Ihrem Dienst in der
AndroidManifest.xmlregistrieren. 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 zum AndroidX Media3-Sitzungsmodul hinzu und entfernen Sie die alte Abhängigkeit:implementation "androidx.media3:media3-session:1.11.1"Ändern Sie Ihren Dienst so, dass er von einem
MediaLibraryServiceanstelle vonMediaBrowserServiceerbt. Wie bereits erwähnt, ist derMediaLibraryServicemit dem Legacy-MediaBrowserServicekompatibel. Dementsprechend ist die umfassendere API, die der Dienst den Clients bietet, immer noch dieselbe. Es ist also wahrscheinlich, dass eine App den Großteil der Logik, die für die Implementierung vonMediaBrowserServiceerforderlich ist, beibehalten und für die neueMediaLibraryServiceanpassen kann.Die Hauptunterschiede im Vergleich zur Legacy-
MediaBrowserServiceCompatsind:Lebenszyklusmethoden des Dienstes implementieren:Die Methoden, die im Dienst selbst überschrieben werden müssen, sind
onCreate/onDestroy. Hier weist eine App die Bibliothekssitzung, den Player und andere Ressourcen zu oder gibt sie frei. Zusätzlich zu den standardmäßigen Lebenszyklusmethoden für Dienste muss eine ApponGetSession(MediaSession.ControllerInfo)überschreiben, um die inonCreateerstellteMediaLibrarySessionzurückzugeben.MediaLibraryService.MediaLibrarySessionCallback implementieren:Zum Erstellen einer Sitzung ist ein
MediaLibraryService.MediaLibrarySessionCallbackerforderlich, der die eigentlichen Domain-API-Methoden implementiert. Anstatt API-Methoden des Legacy-Dienstes zu überschreiben, überschreiben Sie stattdessen die Methoden vonMediaLibrarySession.Callback.Der Callback wird dann verwendet, um die
MediaLibrarySessionzu erstellen:Kotlin
mediaLibrarySession = MediaLibrarySession.Builder(context, player, MySessionCallback()).build()
Java
mediaLibrarySession = new MediaLibrarySession.Builder(context, player, new MySessionCallback()).build();
Die vollständige API von „MediaLibrarySessionCallback“ finden Sie in der API-Dokumentation.
MediaSession.Callback.onAddMediaItems()implementieren: Der CallbackonAddMediaItems(MediaSession, ControllerInfo, List<MediaItem>)dient verschiedenen aktuellen und älteren API-Methoden, mit denen Mediendateien abwärtskompatibel 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 in derPlaybackServiceder Session-Demo-App.AndroidX Media3 verwendet
androidx.media3.common.MediaItemanstelle von MediaBrowserCompat.MediaItem und MediaMetadataCompat. Teile deines Codes, die mit den Legacy-Klassen verknüpft sind, müssen entsprechend geändert oder stattdessen der Media3-MediaItemzugeordnet werden.Das allgemeine asynchrone Programmiermodell wurde in
Futuresgeändert, im Gegensatz zum trennbarenResult-Ansatz vonMediaBrowserServiceCompat. Ihre Dienstimplementierung kann ein asynchronesListenableFuturezurückgeben, anstatt ein Ergebnis zu trennen, oder ein sofortiges Future zurückgeben, um einen Wert direkt zurückzugeben.
PlayerNotificationManager entfernen
Der MediaLibraryService unterstützt Medienbenachrichtigungen automatisch und der PlayerNotificationManager kann entfernt werden, wenn ein MediaLibraryService oder MediaSessionService verwendet wird.
Eine App kann die Benachrichtigung anpassen, indem sie in onCreate() ein benutzerdefiniertes MediaNotification.Provider festlegt, das das DefaultMediaNotificationProvider ersetzt. Der MediaLibraryService startet den Dienst dann nach Bedarf im Vordergrund.
Durch das Überschreiben von MediaLibraryService.updateNotification() kann eine App außerdem die vollständige Kontrolle über 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 Legacy-Welt einen MediaBrowserCompat und einen MediaControllerCompat erstellen mussten, können Sie dasselbe tun, indem Sie nur den MediaBrowser in Media3 verwenden.
Sie können einen MediaBrowser erstellen und warten, bis die Verbindung zum Dienst hergestellt ist:
Kotlin
scope.launch { val sessionToken = SessionToken(context, ComponentName(context, "MusicService")) browser = MediaBrowser.Builder(context, sessionToken) .setListener(BrowserListener()) .buildAsync() .await() }
Java
SessionToken sessionToken = new SessionToken(context, new ComponentName(context, "MusicService")); ListenableFuture<MediaBrowser> browserFuture = new MediaBrowser.Builder(context, sessionToken) .setListener(new BrowserListener()) .buildAsync();
Unter Wiedergabe in der Mediensitzung steuern erfährst du, wie du einen MediaController erstellst, um die Wiedergabe im Hintergrund zu steuern.
Weitere Schritte und Bereinigung
Fehler bei instabiler API
Nach der Migration zu Media3 werden möglicherweise Lint-Fehler zu instabilen API-Nutzungen angezeigt.
Diese APIs können sicher verwendet werden. Die Lint-Fehler sind ein Nebenprodukt unserer neuen Garantien für die Binärkompatibilität. Wenn Sie keine strikte Binärkompatibilität benötigen, können diese Fehler mit einer @OptIn-Annotation sicher unterdrückt werden.
Hintergrund
Weder ExoPlayer v1 noch v2 boten strenge Garantien für die Binärkompatibilität der Bibliothek zwischen nachfolgenden Versionen. Die ExoPlayer API-Oberfläche ist absichtlich sehr groß, damit Apps fast jeden Aspekt der Wiedergabe anpassen können. In nachfolgenden Versionen von ExoPlayer wurden gelegentlich Symbolumbenennungen oder andere funktionsgefährdende Änderungen eingeführt (z.B. neue erforderliche Methoden für Schnittstellen). In den meisten Fällen wurden diese Probleme behoben, indem das neue Symbol eingeführt und das alte Symbol für einige Versionen eingestellt wurde, damit Entwickler Zeit hatten, ihre Verwendungen zu migrieren. Das war jedoch nicht immer möglich.
Diese funktionsgefährdenden Ä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 Code nicht mehr kompiliert wird.
- Bei einer App, die sowohl direkt als auch über eine Zwischenbibliothek von ExoPlayer abhängig war, musste sichergestellt werden, dass beide Abhängigkeiten dieselbe Version hatten. Andernfalls konnten binäre Inkompatibilitäten zu Abstürzen während der Laufzeit führen.
Verbesserungen in Media3
Media3 garantiert die Binärkompatibilität für einen Teil der API-Oberfläche. Die Teile, die keine Binärkompatibilität garantieren, sind mit @UnstableApi gekennzeichnet. Um diese Unterscheidung 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 Lint-Fehler für instabile APIs angezeigt. Dadurch kann der Eindruck entstehen, dass Media3 weniger stabil ist als ExoPlayer v2. Das ist jedoch nicht der Fall. Die „instabilen“ Teile der Media3 API sind genauso stabil 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.
Fehler bei instabilen API-Lint-Fehlern beheben
Weitere Informationen zum Annotieren von Java- und Kotlin-Nutzungen instabiler APIs mit @OptIn finden Sie im Abschnitt zur Fehlerbehebung bei diesen Lint-Fehlern.
Verworfene APIs
In Android Studio sind Aufrufe von verworfenen APIs durchgestrichen. Wir empfehlen, solche Aufrufe durch die entsprechende Alternative zu ersetzen. Bewegen Sie den Mauszeiger auf das Symbol, um das JavaDoc aufzurufen, in dem die zu verwendende API angegeben ist.
Codebeispiele und Demo-Apps
- AndroidX Media3-Sitzungs-Demo-App (Mobilgeräte und Wear OS)
- Benutzerdefinierte Aktionen
- System-UI-Benachrichtigung, MediaButton/BT
- Wiedergabesteuerung mit Google Assistant
- UAMP: Android Media Player (Zweig media3) (Mobilgeräte, AutomotiveOS)
- System-UI-Benachrichtigung, MediaButton/BT, Fortsetzung der Wiedergabe
- Wiedergabesteuerung über Google Assistant/Wear OS
- AutomotiveOS: benutzerdefinierter Befehl und Anmeldung