Le app che attualmente utilizzano la libreria com.google.android.exoplayer2
e androidx.media
autonoma devono eseguire la migrazione in androidx.media3
. Utilizza
lo script di migrazione per eseguire la migrazione dei file di compilazione Gradle, dei file di codice sorgente Java e Kotlin e dei file di layout XML da ExoPlayer2.19.1
ad AndroidX Media3 1.1.1
.
Panoramica
Prima di eseguire la migrazione, esamina le sezioni seguenti per saperne di più sui vantaggi delle nuove API, sulle API di cui eseguire la migrazione e sui prerequisiti che il progetto della tua app deve soddisfare.
Perché eseguire la migrazione a Jetpack Media3
- È la nuova casa di ExoPlayer, mentre
com.google.android.exoplayer2
è stato ritirato. - Accedi all'API Player in più componenti/processi con
MediaBrowser
/MediaController
. - Utilizza le funzionalità estese dell'API
MediaSession
eMediaController
. - Pubblicizza le funzionalità di riproduzione con il controllo dell'accesso granulare.
- Semplifica la tua app rimuovendo
MediaSessionConnector
ePlayerNotificationManager
. - Compatibile con le versioni precedenti con le API client media-compat
(
MediaBrowserCompat
/MediaControllerCompat
/MediaMetadataCompat
)
API multimediali per la migrazione ad AndroidX Media3
- ExoPlayer e le relative estensioni
Sono inclusi tutti i moduli del progetto ExoPlayer precedente, ad eccezione del modulo mediasession non più disponibile. È possibile eseguire la migrazione di app o moduli in base ai pacchetti incom.google.android.exoplayer2
con lo script di migrazione. - MediaSessionConnector (a seconda dei
androidx.media.*
pacchetti diandroidx.media:media:1.4.3+
)
RimuoviMediaSessionConnector
e utilizza inveceandroidx.media3.session.MediaSession
. - MediaBrowserServiceCompat (a seconda dei
androidx.media.*
pacchetti diandroidx.media:media:1.4.3+
)
Esegui la migrazione delle sottoclassi diandroidx.media.MediaBrowserServiceCompat
aandroidx.media3.session.MediaLibraryService
e il codice che utilizzaMediaBrowserCompat.MediaItem
aandroidx.media3.common.MediaItem
. - MediaBrowserCompat (a seconda dei
android.support.v4.media.*
pacchetti diandroidx.media:media:1.4.3+
)
Esegui la migrazione del codice client utilizzandoMediaBrowserCompat
oMediaControllerCompat
per utilizzareandroidx.media3.session.MediaBrowser
conandroidx.media3.common.MediaItem
.
Prerequisiti
Assicurati che il progetto sia sottoposto a controllo del codice sorgente
Assicurati di poter annullare facilmente le modifiche applicate dagli strumenti di migrazione basati su script. Se non hai ancora sottoposto il progetto al controllo del codice sorgente, ora è un buon momento per iniziare. Se per qualche motivo non vuoi farlo, esegui un backup del progetto prima di avviare la migrazione.
Aggiornare la tua app
Ti consigliamo di aggiornare il progetto in modo da utilizzare la versione più recente della libreria ExoPlayer e rimuovere eventuali chiamate a metodi ritirati. Se intendi utilizzare lo script per la migrazione, devi associare la versione a cui stai eseguendo l'aggiornamento alla versione gestita dallo script.
Aumenta il valore compileSdkVersion della tua app ad almeno 32.
Esegui l'upgrade di Gradle e del plug-in Gradle di Android Studio a una versione recente che funzioni con le dipendenze aggiornate riportate sopra. Ad esempio:
- Versione del plug-in Android per Gradle: 7.1.0
- Versione Gradle: 7.4
Sostituisci tutte le istruzioni di importazione con caratteri jolly che utilizzano un asterisco (*) e utilizza istruzioni di importazione completamente qualificate: elimina le istruzioni di importazione con caratteri jolly e utilizza Android Studio per importare le istruzioni completamente qualificate (F2 - Alt/Invio, F2 - Alt/Invio, ...).
Esegui la migrazione da
com.google.android.exoplayer2.PlayerView
acom.google.android.exoplayer2.StyledPlayerView
. Questo è necessario perché non esiste un equivalente dicom.google.android.exoplayer2.PlayerView
in AndroidX Media3.
Esegui la migrazione di ExoPlayer con il supporto dello script
Lo script semplifica il passaggio da com.google.android.exoplayer2
alla nuova struttura di pacchetti e moduli in androidx.media3
. Lo script applica alcuni controlli di convalida al progetto e stampa avvisi se la convalida non va a buon fine.
In caso contrario, applica le mappature di classi e pacchetti rinominati nelle risorse di un progetto gradle per Android scritto in Java o Kotlin.
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
Utilizzo dello script di migrazione
Scarica lo script di migrazione dal tag del progetto ExoPlayer su GitHub corrispondente alla versione a cui hai aggiornato l'app:
curl -o media3-migration.sh \ "https://raw.githubusercontent.com/google/ExoPlayer/r2.19.1/media3-migration.sh"
Rendi eseguibile lo script:
chmod 744 media3-migration.sh
Esegui lo script con
--help
per scoprire di più sulle opzioni.Esegui lo script con
-l
per elencare l'insieme di file selezionati per la migrazione (utilizza-f
per forzare l'elenco senza avvisi):./media3-migration.sh -l -f /path/to/gradle/project/root
Esegui lo script con
-m
per mappare pacchetti, classi e moduli a Media3. L'esecuzione dello script con l'opzione-m
applicherà le modifiche ai file selezionati.- Interrompi in caso di errore di convalida senza apportare modifiche
./media3-migration.sh -m /path/to/gradle/project/root
- Esecuzione forzata
Se lo script rileva una violazione dei prerequisiti, la migrazione può essere forzata con il flag
-f
:./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
Completa questi passaggi manuali dopo aver eseguito lo script con l'opzione -m
:
- Controlla in che modo lo script ha modificato il codice: utilizza uno strumento per le differenze e risolvi
potenziali problemi (valuta la possibilità di segnalare un bug se ritieni che lo script abbia un
problema generale introdotto senza trasmettere l'opzione
-f
). - Compila il progetto: utilizza
./gradlew clean build
o in Android Studio scegli File > Sincronizza progetto con i file Gradle, quindi Compila > Pulisci progetto e infine Compila > Ricompila progetto (monitora la compilazione nella scheda "Compila - Output compilazione" di Android Studio.
Passaggi successivi consigliati:
- Risolvi i problemi relativi all'attivazione per gli errori relativi all'utilizzo di API instabili.
- Sostituisci le chiamate API ritirate: utilizza l'API sostitutiva suggerita. Passa il cursore sopra l'avviso in Android Studio e consulta la documentazione Java del simbolo ritirato per scoprire cosa utilizzare al posto di una determinata chiamata.
- Ordina le istruzioni di importazione: apri il progetto in Android Studio, poi fai clic con il tasto destro del mouse su un nodo della cartella del pacchetto nel visualizzatore del progetto e scegli Ottimizza importazioni sui pacchetti che contengono i file di origine modificati.
Sostituisci MediaSessionConnector
con androidx.media3.session.MediaSession
Nel mondo precedente di MediaSessionCompat
, MediaSessionConnector
era responsabile della sincronizzazione dello stato del player con lo stato della sessione e della ricezione di comandi dai controller che dovevano essere delegati ai metodi del player appropriati. Con AndroidX Media3, MediaSession
esegue direttamente questa operazione
senza richiedere un connettore.
Rimuovi tutti i riferimenti e l'utilizzo di MediaSessionConnector: se hai utilizzato lo script automatico per eseguire la migrazione delle classi e dei pacchetti ExoPlayer, è probabile che lo script abbia lasciato il codice in uno stato non compilabile per quanto riguarda
MediaSessionConnector
che non può essere risolto. Android Studio ti mostrerà il codice non valido quando provi a compilare o avviare l'app.Nel file
build.gradle
in cui gestisci le dipendenze, aggiungi una dipendenza di implementazione al modulo della sessione AndroidX Media3 e rimuovi la dipendenza precedente:implementation "androidx.media3:media3-session:1.4.1"
Sostituisci
MediaSessionCompat
conandroidx.media3.session.MediaSession
.Nel sito del codice in cui hai creato
MediaSessionCompat
precedente, utilizzaandroidx.media3.session.MediaSession.Builder
per creare unMediaSession
. Passa il player per creare lo Strumento per la creazione di sessioni.val player = ExoPlayer.Builder(context).build() mediaSession = MediaSession.Builder(context, player) .setSessionCallback(MySessionCallback()) .build()
Implementa
MySessionCallback
come richiesto dalla tua app. Questa opzione è facoltativa. Se vuoi consentire ai controller di aggiungere elementi multimediali al player, implementaMediaSession.Callback.onAddMediaItems()
. Supporta vari metodi API attuali e legacy che aggiungono elementi multimediali al player per la riproduzione in modo compatibile con le versioni precedenti. Sono inclusi i metodiMediaController.set/addMediaItems()
del controller Media3 e i metodiTransportControls.prepareFrom*/playFrom*
dell'API legacy. Un'implementazione di esempio dionAddMediaItems
è disponibile nelPlaybackService
dell'app demo della sessione.Rilascia la sessione multimediale sul sito del codice in cui hai distrutto la sessione prima della migrazione:
mediaSession?.run { player.release() release() mediaSession = null }
Funzionalità MediaSessionConnector
in Media3
La tabella seguente mostra le API Media3 che gestiscono le funzionalità precedentemente implementate in MediaSessionConnector
.
MediaSessionConnector | AndroidX Media3 |
---|---|
CustomActionProvider |
MediaSession.Callback.onCustomCommand()/
MediaSession.setCustomLayout() |
PlaybackPreparer |
MediaSession.Callback.onAddMediaItems()
(prepare() viene chiamato internamente)
|
QueueNavigator |
ForwardingPlayer |
QueueEditor |
MediaSession.Callback.onAddMediaItems() |
RatingCallback |
MediaSession.Callback.onSetRating() |
PlayerNotificationManager |
DefaultMediaNotificationProvider/
MediaNotification.Provider |
Esegui la migrazione di MediaBrowserService
a MediaLibraryService
AndroidX Media3 introduce MediaLibraryService
che sostituisce
MediaBrowserServiceCompat
. La documentazione Java di MediaLibraryService
e della sua super classa MediaSessionService
fornisce una buona introduzione all'API e al modello di programmazione asincrona del servizio.
MediaLibraryService
è compatibile con le versioni precedenti di MediaBrowserService
. Un'app client che utilizza MediaBrowserCompat
o
MediaControllerCompat
continua a funzionare senza modifiche al codice quando si connette
a un MediaLibraryService
. Per un client, è trasparente se la tua app utilizza
un MediaLibraryService
o una versione MediaBrowserServiceCompat
precedente.
Affinché la compatibilità con le versioni precedenti funzioni, devi registrare entrambe le interfacce di servizio con il tuo servizio in
AndroidManifest.xml
. In questo modo, un client trova il tuo servizio in base all'interfaccia di servizio richiesta:<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>
Nel file
build.gradle
in cui gestisci le dipendenze, aggiungi una dipendenza di implementazione al modulo di sessione AndroidX Media3 e rimuovi la dipendenza precedente:implementation "androidx.media3:media3-session:1.4.1"
Modifica il servizio in modo che erediti da un
MediaLibraryService
anziché daMediaBrowserService
Come detto in precedenza,MediaLibraryService
è compatibile con la versione precedenteMediaBrowserService
. Di conseguenza, l'API più ampia offerta dal servizio ai clienti rimane invariata. Pertanto, è probabile che un'app possa mantenere gran parte della logica necessaria per implementare ilMediaBrowserService
e adattarla al nuovoMediaLibraryService
.Le principali differenze rispetto alla versione precedente
MediaBrowserServiceCompat
sono le seguenti:Implementa i metodi del ciclo di vita dei servizi: i metodi che devono essere sottoposti a override nel servizio stesso sono
onCreate/onDestroy
, in cui un'app alloca/rilascia la sessione della libreria, il player e altre risorse. Oltre ai metodi di ciclo di vita del servizio standard, un'app deve eseguire l'override dionGetSession(MediaSession.ControllerInfo)
per restituire ilMediaLibrarySession
creato inonCreate
.Implementa MediaLibraryService.MediaLibrarySessionCallback: la creazione di una sessione richiede un
MediaLibraryService.MediaLibrarySessionCallback
che implementi i metodi dell'API di dominio effettiva. Pertanto, anziché eseguire l'override dei metodi dell'API del servizio precedente, dovrai eseguire l'override dei metodi diMediaLibrarySession.Callback
.Il callback viene poi utilizzato per creare
MediaLibrarySession
:mediaLibrarySession = MediaLibrarySession.Builder(this, player, MySessionCallback()) .build()
Trova l'API completa di MediaLibrarySessionCallback nella documentazione dell'API.
Implementa
MediaSession.Callback.onAddMediaItems()
: il callbackonAddMediaItems(MediaSession, ControllerInfo, List<MediaItem>)
fornisce vari metodi API attuali e legacy che aggiungono elementi multimediali al player per la riproduzione in modo compatibile con le versioni precedenti. Sono inclusi i metodiMediaController.set/addMediaItems()
del controller Media3, nonché i metodiTransportControls.prepareFrom*/playFrom*
dell'API precedente. Un'implementazione di esempio del callback è disponibile inPlaybackService
dell'app demo della sessione.AndroidX Media3 utilizza
androidx.media3.common.MediaItem
anziché MediaBrowserCompat.MediaItem e MediaMetadataCompat. Le parti del codice associate alle classi precedenti devono essere modificate di conseguenza o mappate a Media3MediaItem
.Il modello di programmazione asincrona generale è stato modificato in
Futures
in contrapposizione all'approccioResult
scollegabile delMediaBrowserServiceCompat
. L'implementazione del servizio può restituire unListenableFuture
asincrono anziché scollegare un risultato o restituire un Future immediato per restituire direttamente un valore.
Rimuovi PlayerNotificationManager
Il MediaLibraryService
supporta automaticamente le notifiche relative ai contenuti multimediali e
la PlayerNotificationManager
può essere rimossa quando utilizzi MediaLibraryService
o
MediaSessionService
.
Un'app può personalizzare la notifica impostando un valore personalizzato
MediaNotification.Provider
in onCreate()
che sostituisce il valore
DefaultMediaNotificationProvider
. MediaLibraryService
si occupa quindi di avviare il servizio in primo piano, come richiesto.
Se esegui l'override di MediaLibraryService.updateNotification()
, un'app può acquisire ulteriormente
la piena proprietà della pubblicazione di una notifica e dell'avvio/arresto del servizio in primo piano, come richiesto.
Esegui la migrazione del codice client utilizzando un MediaBrowser
Con AndroidX Media3, un MediaBrowser
implementa le interfacce MediaController/Player
e può essere utilizzato per controllare la riproduzione dei contenuti multimediali oltre a sfogliare la raccolta multimediale. Se in precedenza dovevi creare un MediaBrowserCompat
e un
MediaControllerCompat
, puoi fare lo stesso utilizzando solo
MediaBrowser
in Media3.
È possibile creare un MediaBrowser
e attendere che venga stabilita la connessione al servizio:
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)
}
Consulta la sezione Controllare la riproduzione nella sessione multimediale per scoprire come creare un MediaController
per controllare la riproduzione in background.
Ulteriori passaggi e pulizia
Errori dell'API instabili
Dopo la migrazione a Media3, potresti visualizzare errori di lint relativi a utilizzi instabili dell'API.
Queste API sono sicure da utilizzare e gli errori lint sono un sottoprodotto delle nostre nuove garanzie di compatibilità binaria. Se non hai bisogno di una rigorosa compatibilità binaria, questi errori possono essere eliminati in modo sicuro con un'annotazione
@OptIn
.
Background
Né la versione 1 né la versione 2 di ExoPlayer fornivano garanzie rigorose sulla compatibilità binaria della libreria tra le versioni successive. L'API ExoPlayer è molto grande per design, in modo da consentire alle app di personalizzare quasi ogni aspetto della riproduzione. Le versioni successive di ExoPlayer introducevano occasionalmente rinominazioni di simboli o altre modifiche incompatibili (ad es. nuovi metodi obbligatori sulle interfacce). Nella maggior parte dei casi, questi problemi sono stati attenuati introducendo il nuovo simbolo e ritirando il vecchio simbolo per alcune versioni, per consentire agli sviluppatori di eseguire la migrazione dei loro utilizzi, ma non è sempre stato possibile.
Queste modifiche non compatibili hanno causato due problemi per gli utenti delle librerie ExoPlayer v1 e v2:
- Un upgrade alla versione ExoPlayer potrebbe causare l'interruzione della compilazione del codice.
- Un'app che dipendeva da ExoPlayer sia direttamente sia tramite una raccolta intermedia doveva assicurarsi che entrambe le dipendenze avessero la stessa versione, altrimenti le incompatibilità binarie potevano causare arresti anomali in fase di esecuzione.
Miglioramenti in Media3
Media3 garantisce la compatibilità binaria per un sottoinsieme della piattaforma API. Le parti che non garantiscono la compatibilità binaria sono contrassegnate da @UnstableApi
. Per chiarire questa distinzione, l'utilizzo di simboli API instabili genera un errore di lint, a meno che non siano annotati con @OptIn
.
Dopo la migrazione da ExoPlayer 2 a Media3, potresti visualizzare molti errori di lint dell'API instabili. Ciò potrebbe far sembrare che Media3 sia "meno stabile" di ExoPlayer v2. Non è così. Le parti "instabili" dell'API Media3 hanno lo stesso livello di stabilità dell'intero API ExoPlayer v2 e le garanzie dell'API Media3 stabile non sono affatto disponibili in ExoPlayer v2. La differenza sta semplicemente nel fatto che ora un errore di lint indica i diversi livelli di stabilità.
Gestire gli errori di lint dell'API instabili
Consulta la sezione per la risoluzione dei problemi relativi a questi errori di lint per dettagli su come annotare gli utilizzi di Java e Kotlin di API instabili con @OptIn
.
API deprecate
Potresti notare che le chiamate alle API deprecate vengono barrate in Android Studio. Ti consigliamo di sostituire queste chiamate con l'alternativa appropriata. Passa il mouse sopra il simbolo per visualizzare la documentazione JavaDoc che indica quale API utilizzare.
Esempi di codice e app di dimostrazione
- App demo della sessione AndroidX Media3 (dispositivi mobili e WearOS)
- Azioni personalizzate
- Notifica UI di sistema, MediaButton/BT
- Controllo della riproduzione con l'Assistente Google
- UAMP: Android Media Player (branch media3) (mobile, AutomotiveOS)
- Notifica dell'interfaccia utente di sistema, tasto multimediale/Bluetooth, ripresa della riproduzione
- Controllo di riproduzione con l'Assistente Google/Wear OS
- AutomotiveOS: comando e accesso personalizzati