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 migrieren, lesen Sie die folgenden Abschnitte, 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. - Mit
MediaBrowser/MediaControllerauf die Player API über Komponenten/Prozesse hinweg zugreifen. - Die erweiterten Funktionen der
MediaSessionundMediaControllerAPI verwenden. - Wiedergabefunktionen mit detaillierter Zugriffssteuerung bewerben.
- App vereinfachen , indem Sie
MediaSessionConnectorundPlayerNotificationManagerentfernen. - Abwärtskompatibel mit Media-Compat-Client-APIs (
MediaBrowserCompat/MediaControllerCompat/MediaMetadataCompat)
Media APIs zu AndroidX Media3 migrieren
- 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.exoplayer2abhängen, können mit dem Migrationsskript migriert werden. - MediaSessionConnector (abhängig von den
androidx.media.*Paketen vonandroidx.media:media:1.4.3+)
Entfernen SieMediaSessionConnectorund verwenden Sie stattdientandroidx.media3.session.MediaSession. - MediaBrowserServiceCompat (abhängig von den
androidx.media.*Paketen vonandroidx.media:media:1.4.3+)
Migrieren Sie 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+)
Migrieren Sie Clientcode, derMediaBrowserCompatoderMediaControllerCompatverwendet, zuandroidx.media3.session.MediaBrowsermitandroidx.media3.common.MediaItem.
Vorbereitung
Achten Sie darauf, dass Ihr Projekt unter Quellcodeverwaltung steht.
So können Sie Änderungen, die von skriptbasierten Migrationstools vorgenommen wurden, ganz einfach rückgängig machen. Wenn Ihr Projekt noch nicht unter Quellcodeverwaltung steht, ist jetzt ein guter Zeitpunkt, damit zu beginnen. Wenn Sie das aus irgendeinem Grund nicht 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 veralteter 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 aktualisierten Abhängigkeiten von oben funktioniert. Beispiel:
- Android Gradle-Plug-in-Version: 7.1.0
- Gradle-Version: 7.4
Ersetzen Sie alle Platzhalter-Importanweisungen , die ein Sternchen (*) verwenden, durch vollständig qualifizierte Importanweisungen: Löschen Sie die Platzhalter-Importanweisungen und importieren Sie die vollständig qualifizierten Anweisungen mit Android Studio (F2 – Alt/Eingabe, F2 – Alt/Eingabe usw.).
Migrieren Sie von
com.google.android.exoplayer2.PlayerViewzucom.google.android.exoplayer2.StyledPlayerView. Das ist erforderlich, da es in AndroidX Media3 kein Äquivalent zucom.google.android.exoplayer2.PlayerViewgibt.
ExoPlayer mit Skriptunterstützung migrieren
Das Skript erleichtert den Wechsel 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 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 Gruppe der Dateien aufzulisten, die für die Migration ausgewählt wurden. Verwenden Sie-f, um die Auflistung ohne Warnungen zu erzwingen:./media3-migration.sh -l -f /path/to/gradle/project/rootFühren Sie das Skript mit
-maus, um Pakete, Klassen und Module Media3 zuzuordnen. Wenn Sie das Skript mit der Option-mausführen, werden Änderungen an den ausgewählten Dateien vorgenommen.- Bei Validierungsfehler ohne Änderungen anhalten
./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
-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 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. Melden Sie einen Fehler, wenn Sie der Meinung sind, dass das Skript ein allgemeines Problem hat, das ohne die Option
-feingeführt wurde. - Erstellen Sie das Projekt: Verwenden Sie entweder
./gradlew clean buildoder wählen Sie in Android Studio Datei > Projekt mit Gradle-Dateien synchronisieren und dann Erstellen > Projekt bereinigen und dann Erstellen > Projekt neu erstellen aus. Beobachten Sie den Build auf dem Tab „Build – Build-Ausgabe“ von Android Studio.
Empfohlene Folgeschritte:
- Opt-in für Fehler bezüglich der Verwendung instabiler APIs beheben.
- Veraltete API-Aufrufe ersetzen: Verwenden Sie die vorgeschlagene Ersatz-API. Bewegen Sie den Mauszeiger in Android Studio auf die Warnung und lesen Sie die JavaDoc des veralteten Symbols, um herauszufinden, was Sie anstelle eines bestimmten Aufrufs verwenden können.
- Importanweisungen sortieren: Öffnen Sie das Projekt in Android Studio, klicken Sie dann im Projekt-Viewer mit der rechten Maustaste auf einen Paketordnerknoten und wählen Sie für die Pakete, die die geänderten Quelldateien enthalten, Importe optimieren aus.
MediaSessionConnector durch androidx.media3.session.MediaSession ersetzen
In der alten MediaSessionCompat-Welt war MediaSessionConnector für die Synchronisierung des Player-Status mit dem Status der Sitzung und für den Empfang von Befehlen von Controllern zuständig, die an geeignete Player-Methoden delegiert werden mussten. Mit AndroidX Media3 wird dies direkt von MediaSession ohne Connector erledigt.
Alle Verweise und Verwendungen von MediaSessionConnector entfernen:Wenn Sie das automatisierte Skript verwendet haben, um ExoPlayer-Klassen und -Pakete zu migrieren, hat das Skript Ihren Code wahrscheinlich in einem nicht kompilierbaren Zustand bezüglich
MediaSessionConnectorbelassen, der nicht behoben 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.10.0"Ersetzen Sie
MediaSessionCompatdurchandroidx.media3.session.MediaSession.Verwenden Sie an der Codestelle, an der Sie die alte
MediaSessionCompaterstellt haben,androidx.media3.session.MediaSession.Builderum eineMediaSessionzu erstellen. Übergeben Sie den Player , um den Sitzungs-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
MySessionCallbacknach Bedarf für Ihre App. Das ist optional. Wenn Sie Controllern erlauben möchten, dem Player Media-Elemente hinzuzufügen, implementieren SieMediaSession.Callback.onAddMediaItems(). Es stellt verschiedene aktuelle und alte API-Methoden bereit, mit denen Mediendateien auf abwärtskompatible Weise dem Player zur Wiedergabe hinzugefügt werden. Dazu gehören die MethodenMediaController.set/addMediaItems()des Media3-Controllers sowie die MethodenTransportControls.prepareFrom*/playFrom*der alten API. Eine Beispielimplementierung vononAddMediaItemsfinden Sie in derPlaybackServiceder Sitzungs-Demo-App.Geben Sie die Media-Session an der Codestelle frei, an der Sie Ihre Sitzung vor der Migration beendet haben:
Kotlin
mediaSession?.run { player.release() release() mediaSession = null }
Java
if (mediaSession != null) { mediaSession.getPlayer().release(); mediaSession.release(); mediaSession = null; }
MediaSessionConnector-Funktionalität 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. Die JavaDoc von MediaLibraryService und seiner Superklasse MediaSessionService bietet eine gute Einführung in die API und das asynchrone Programmiermodell des Dienstes.
MediaLibraryService ist abwärtskompatibel mit MediaBrowserService. Eine Client-App, die MediaBrowserCompat oder MediaControllerCompat verwendet, funktioniert weiterhin ohne Codeänderungen, wenn sie eine Verbindung zu MediaLibraryService herstellt. Für einen Client ist es transparent, ob Ihre App MediaLibraryService oder das alte MediaBrowserServiceCompat verwendet.
Damit die Abwärtskompatibilität funktioniert, müssen Sie beide Dienstschnittstellen in der
AndroidManifest.xmlbei Ihrem Dienst 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 zum AndroidX Media3-Sitzungsmodul hinzu und entfernen Sie die alte Abhängigkeit:implementation "androidx.media3:media3-session:1.10.0"Ändern Sie Ihren Dienst so, dass er von
MediaLibraryServiceanstelle vonMediaBrowserServiceerbt. Wie bereits erwähnt, istMediaLibraryServicemit dem altenMediaBrowserServicekompatibel. Dementsprechend ist die breitere API, die der Dienst Clients anbietet, immer noch dieselbe. Es ist also wahrscheinlich, dass eine App die meiste Logik beibehalten kann, die zur Implementierung vonMediaBrowserServiceerforderlich ist, und sie für das neueMediaLibraryServiceanpassen kann.Die Hauptunterschiede im Vergleich zu
MediaBrowserServiceCompatsind folgende:Implementieren Sie die Methoden des Dienstlebenszyklus: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 bzw. gibt sie frei. Zusätzlich zu den Standardmethoden des Dienstlebenszyklus muss eine ApponGetSession(MediaSession.ControllerInfo)überschreiben, um dieMediaLibrarySessionzurückzugeben, die inonCreateerstellt wurde.Implementieren Sie MediaLibraryService.MediaLibrarySessionCallback: Zum Erstellen einer Sitzung ist ein
MediaLibraryService.MediaLibrarySessionCallbackerforderlich, das die tatsächlichen Domain-API-Methoden implementiert. Anstatt also API-Methoden des alten 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.
Implementieren Sie
MediaSession.Callback.onAddMediaItems(): Der CallbackonAddMediaItems(MediaSession, ControllerInfo, List<MediaItem>)stellt verschiedene aktuelle und alte API-Methoden bereit, mit denen Mediendateien auf abwärtskompatible Weise dem Player zur Wiedergabe hinzugefügt werden. Dazu gehören die MethodenMediaController.set/addMediaItems()des Media3-Controllers sowie die MethodenTransportControls.prepareFrom*/playFrom*der alten API. Eine Beispielimplementierung des Callbacks kann gefunden werden in derPlaybackServiceder Sitzungs-Demo-App.AndroidX Media3 verwendet
androidx.media3.common.MediaItemanstelle von MediaBrowserCompat.MediaItem und MediaMetadataCompat. Teile Ihres Codes, die an die alten Klassen gebunden sind, müssen entsprechend geändert oder stattdessen auf das Media3-MediaItemabgebildet werden.Das allgemeine asynchrone Programmiermodell wurde in
Futuresgeändert, im Gegensatz zum abtrennbarenResult-Ansatz vonMediaBrowserServiceCompat. Ihre Dienstimplementierung kann ein asynchronesListenableFuturezurückgeben, anstatt ein Ergebnis abzutrennen, oder ein sofortiges Future zurückgeben, um direkt einen Wert zurückzugeben.
PlayerNotificationManager entfernen
MediaLibraryService unterstützt automatisch Media-Benachrichtigungen und PlayerNotificationManager kann entfernt werden, wenn Sie MediaLibraryService oder MediaSessionService verwenden.
Eine App kann die Benachrichtigung anpassen , indem sie in onCreate() einen benutzerdefinierten MediaNotification.Provider festlegt, der DefaultMediaNotificationProvider ersetzt. MediaLibraryService startet den Dienst dann nach Bedarf im Vordergrund.
Durch Überschreiben von MediaLibraryService.updateNotification() kann eine App 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 Schnittstellen MediaController/Player und kann neben dem Durchsuchen der Media-Bibliothek 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 in Media3 nur
das MediaBrowser verwenden.
Ein MediaBrowser kann erstellt werden und auf die Herstellung der Verbindung zum Dienst warten:
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 Media-Session steuern
erfahren Sie, wie Sie einen MediaController erstellen, um die Wiedergabe im
Hintergrund zu steuern.
Weitere Schritte und Bereinigung
Fehler bei instabilen APIs
Nach der Migration zu Media3 werden möglicherweise Lint-Fehler bezüglich der Verwendung instabiler APIs angezeigt.
Diese APIs können sicher verwendet werden und die Lint-Fehler sind ein Nebenprodukt unserer neuen Garantien für die binäre Kompatibilität. Wenn Sie keine strenge binäre Kompatibilität benötigen, können diese Fehler mit der Annotation @OptIn sicher unterdrückt werden.
Hintergrund
Weder ExoPlayer v1 noch v2 boten strenge Garantien für die binäre Kompatibilität der Bibliothek zwischen nachfolgenden Versionen. Die ExoPlayer API-Oberfläche ist von Natur aus sehr groß, damit Apps fast jeden Aspekt der Wiedergabe anpassen können. In nachfolgenden Versionen von ExoPlayer wurden gelegentlich Symbole umbenannt oder andere Breaking Changes eingeführt (z.B. neue erforderliche Methoden für Schnittstellen). In den meisten Fällen wurden diese Breaking Changes dadurch gemildert, dass das neue Symbol eingeführt und das alte Symbol für einige Versionen als veraltet markiert wurde, damit Entwickler Zeit hatten, ihre Verwendungen zu migrieren. Das war jedoch nicht immer möglich.
Diese Breaking Changes führten zu zwei Problemen für Nutzer der ExoPlayer v1- und v2-Bibliotheken:
- Ein Upgrade von auf die ExoPlayer-Version konnte dazu führen, dass der Code nicht mehr kompiliert wurde.
- Eine App, die sowohl direkt als auch über eine Zwischenbibliothek von ExoPlayer abhing, musste dafür sorgen, 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 eine Teilmenge der API-Oberfläche. Die
Teile, für die keine binäre Kompatibilität garantiert wird, sind mit
@UnstableApi gekennzeichnet. Um diese Unterscheidung deutlich zu machen, wird bei der Verwendung instabiler API-Symbole ein Lint-Fehler generiert, es sei denn, sie sind mit @OptIn annotiert.
Nach der Migration von ExoPlayer v2 zu Media3 werden möglicherweise viele Lint-Fehler für instabile APIs angezeigt. Dadurch kann es so aussehen, als wäre Media3 weniger stabil als ExoPlayer v2. Das stimmt nicht. Die „instabilen“ Teile der Media3 API haben die gleiche Stabilität 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 unterschiedlichen Stabilitätsstufen aufmerksam gemacht werden.
Lint-Fehler für instabile APIs behandeln
Siehe den Abschnitt zur Fehlerbehebung zu diesen Lint-Fehlern für Details dazu, wie Sie
Java- und Kotlin-Verwendungen instabiler APIs mit @OptIn annotieren.
Veraltete APIs
Möglicherweise werden Aufrufe veralteter APIs in Android Studio durchgestrichen. Wir empfehlen, solche Aufrufe durch die entsprechende Alternative zu ersetzen. Bewegen Sie den Mauszeiger auf das Symbol, um die JavaDoc aufzurufen, in der die stattdessen 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 Mediaplayer (Branch media3) (Mobilgeräte, AutomotiveOS)
- System-UI-Benachrichtigung, MediaButton/BT, Wiedergabe fortsetzen
- Wiedergabesteuerung mit Google Assistant/Wear OS
- AutomotiveOS: benutzerdefinierter Befehl und Anmeldung