Şu anda bağımsız com.google.android.exoplayer2
kitaplığını ve androidx.media
sürümünü kullanan uygulamalar androidx.media3
ürününe taşınmalıdır. Gradle derleme dosyalarını, Java ve Kotlin kaynak dosyalarını ve XML düzen dosyalarını ExoPlayer2.19.1
'dan AndroidX Media3 1.1.1
'e taşımak için taşıma komut dosyasını kullanın.
Genel bakış
Taşıma işleminden önce, yeni API'lerin avantajları, taşınacak API'ler ve uygulamanızın projesinin karşılaması gereken ön koşullar hakkında daha fazla bilgi edinmek için aşağıdaki bölümleri inceleyin.
Neden Jetpack Media3'e geçiş yapmalısınız?
- Burası, ExoPlayer'ın yeni yeridir, ancak
com.google.android.exoplayer2
kullanımdan kaldırılmıştır. MediaBrowser
/MediaController
ile bileşenler/işlemler genelinde Player API'ye erişin.MediaSession
veMediaController
API'nin genişletilmiş özelliklerini kullanın.- Ayrıntılı erişim denetimi ile oynatma özelliklerinin reklamını yapın.
MediaSessionConnector
vePlayerNotificationManager
öğelerini kaldırarak uygulamanızı basitleştirin.- Medya uyumlu istemci API'leriyle geriye dönük uyumluluğa sahip
(
MediaBrowserCompat
/MediaControllerCompat
/MediaMetadataCompat
)
AndroidX Media3'e taşınacak medya API'leri
- ExoPlayer ve uzantıları
Buna, kullanımdan kaldırılan mediasession modülü hariç eski ExoPlayer projesinin tüm modülleri dahildir.com.google.android.exoplayer2
içindeki paketlere bağlı olarak uygulama veya modüller, taşıma komut dosyasıyla taşınabilir. - MediaSessionConnector (
androidx.media:media:1.4.3+
androidx.media.*
paketlerine bağlı olarak)
MediaSessionConnector
öğesini kaldırın ve bunun yerineandroidx.media3.session.MediaSession
kullanın. - MediaBrowserServiceCompat (
androidx.media:media:1.4.3+
adlı öğeninandroidx.media.*
paketlerine bağlı olarak)
androidx.media.MediaBrowserServiceCompat
alt sınıflarınıandroidx.media3.session.MediaLibraryService
veMediaBrowserCompat.MediaItem
ileandroidx.media3.common.MediaItem
arasındaki kodu taşıyın. - MediaBrowserCompat (
androidx.media:media:1.4.3+
'ınandroid.support.v4.media.*
paketlerine bağlı olarak)
androidx.media3.session.MediaBrowser
'yiandroidx.media3.common.MediaItem
ile kullanmak içinMediaBrowserCompat
veyaMediaControllerCompat
ile istemci kodunu taşıyın.
Ön koşullar
Projenizin kaynak kontrolü altında olduğundan emin olma
Komut dosyası kullanılan taşıma araçları tarafından uygulanan değişiklikleri kolayca geri alabileceğinizden emin olun. Projeniz henüz kaynak kontrolü altında değilse projeye hemen başlayabilirsiniz. Herhangi bir nedenle bunu yapmak istemezseniz taşıma işlemine başlamadan önce projenizin yedek bir kopyasını oluşturun.
Uygulamanızı güncelleme
Projenizi ExoPlayer kitaplığının en son sürümünü kullanacak şekilde güncellemenizi ve kullanımdan kaldırılan yöntemlere yapılan tüm çağrıları kaldırmanızı öneririz. Taşıma işlemi için komut dosyasını kullanmayı planlıyorsanız güncelleme yaptığınız sürümü, komut dosyası tarafından işlenen sürümle eşleştirmeniz gerekir.
Uygulamanızın BuildSdkVersion değerini en az 32'ye yükseltin.
Gradle'ı ve Android Studio Gradle eklentisini, yukarıda belirtilen güncel bağımlılıklarla çalışan yeni bir sürüme geçirin. Örneğin:
- Android Gradle Plugin sürümü: 7.1.0
- Gradle sürümü: 7.4
Yıldız işareti (*) kullanan tüm joker karakter içe aktarma ifadelerini değiştirin ve tam nitelikli içe aktarma ifadeleri kullanın: Joker karakter içe aktarma ifadelerini silin ve tam nitelikli ifadeleri (F2 - Alt/Enter, F2 - Alt/Enter, ...) içe aktarmak için Android Studio'yu kullanın.
com.google.android.exoplayer2.PlayerView
'tencom.google.android.exoplayer2.StyledPlayerView
'e geçiş. Bu, AndroidX Media3'tecom.google.android.exoplayer2.PlayerView
eşdeğeri olmadığından gereklidir.
ExoPlayer'ı komut dosyası desteğiyle taşıma
Komut dosyası, com.google.android.exoplayer2
ürününden androidx.media3
altındaki yeni paket ve modül yapısına geçişi kolaylaştırır. Komut dosyası, projenize bazı doğrulama kontrolleri uygular ve doğrulama başarısız olursa uyarılar yazdırır.
Aksi takdirde, Java veya Kotlin'de yazılmış bir Android gradle projesinin kaynaklarında yeniden adlandırılan sınıfların ve paketlerin eşlemelerini uygular.
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
Taşıma komut dosyasını kullanma
Uygulamanızı güncellediğiniz sürüme karşılık gelen taşıma komut dosyasını GitHub'daki ExoPlayer projesinin etiketinden indirin:
curl -o media3-migration.sh \ "https://raw.githubusercontent.com/google/ExoPlayer/r2.19.1/media3-migration.sh"
Komut dosyasını yürütülebilir hale getirin:
chmod 744 media3-migration.sh
Seçenekler hakkında bilgi edinmek için komut dosyasını
--help
ile çalıştırın.Taşıma için seçilen dosya grubunu listelemek üzere komut dosyasını
-l
ile çalıştırın (girişi uyarı yapılmadan zorlamak için-f
kodunu kullanın):./media3-migration.sh -l -f /path/to/gradle/project/root
Paketleri, sınıfları ve modülleri Media3 ile eşlemek için komut dosyasını
-m
ile çalıştırın. Komut dosyası-m
seçeneğiyle çalıştırıldığında, değişiklikler seçili dosyalara uygulanır.- Doğrulama hatasında değişiklik yapmadan durdur
./media3-migration.sh -m /path/to/gradle/project/root
- Zorunlu yürütme
Komut dosyası ön koşulların ihlal edildiğini tespit ederse taşıma işlemi
-f
işaretiyle zorunlu kılınabilir:./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
Komut dosyasını -m
seçeneğiyle çalıştırdıktan sonra bu manuel adımları tamamlayın:
- Komut dosyasının kodunuzu nasıl değiştirdiğini kontrol edin: Bir fark aracı kullanın ve olası sorunları düzeltin (komut dosyasının
-f
seçeneği geçilmeden ortaya çıkan genel bir sorunu olduğunu düşünüyorsanız hata bildirmeyi düşünün). - Projeyi oluşturma:
./gradlew clean build
komutunu kullanın veya Android Studio'da Dosya > Projeyi Gradle Dosyaları ile Senkronize Et'i, ardından Derleme > Projeyi temizle'yi ve Derleme > Projeyi yeniden oluştur'u seçin (Derlemenizi Android Studio'nun "Derleme - Çıktı" sekmesinden izleyin.
Takip edilmesi önerilen adımlar:
- Kararsız API'lerin kullanımıyla ilgili hataları etkinleştirme sorununu çözün.
- Kullanımdan kaldırılan API çağrılarını değiştirme: Önerilen değişim API'sini kullanın. İşaretçiyi Android Studio'daki uyarının üzerine getirin ve belirli bir çağrı yerine ne kullanacağınızı öğrenmek için kullanımdan kaldırılan simgenin JavaDoc'una bakın.
- İçe aktarma ifadelerini sıralama: Projeyi Android Studio'da açın, ardından proje görüntüleyicide bir paket klasörü düğümünü sağ tıklayın ve değiştirilen kaynak dosyaları içeren paketlerde İçe aktarma işlemlerini optimize et'i seçin.
MediaSessionConnector
yerine androidx.media3.session.MediaSession
kullanın
Eski MediaSessionCompat
dünyasında MediaSessionConnector
, oynatıcının durumunu oturumun durumuyla senkronize etmekten ve uygun oynatıcı yöntemlerine yetki verilmesi gereken kumandalardan komut almaktan sorumluydu. AndroidX Media3'te bu işlem doğrudan MediaSession
tarafından bağlayıcı gerektirmeden yapılır.
MediaSessionConnector'ın tüm referanslarını ve kullanımını kaldırın: ExoPlayer sınıflarını ve paketlerini taşımak için otomatik komut dosyası kullandıysanız komut dosyası, muhtemelen kodunuzu, çözülemeyen
MediaSessionConnector
ile ilgili derlenemez bir durumda bırakmıştır. Android Studio, uygulamayı derlemeye veya başlatmaya çalışırken bozuk kodu gösterir.Bağımlılıklarınızı yönettiğiniz
build.gradle
dosyasında, AndroidX Media3 oturum modülüne bir uygulama bağımlılığı ekleyin ve eski bağımlılığı kaldırın:implementation "androidx.media3:media3-session:1.3.1"
MediaSessionCompat
kısmınıandroidx.media3.session.MediaSession
ile değiştirin.Eski
MediaSessionCompat
kodunu oluşturduğunuz kod sitesindeMediaSession
oluşturmak içinandroidx.media3.session.MediaSession.Builder
kodunu kullanın. Oturum oluşturucuyu oluşturmak için oynatıcıyı iletin.val player = ExoPlayer.Builder(context).build() mediaSession = MediaSession.Builder(context, player) .setSessionCallback(MySessionCallback()) .build()
ForwardingPlayer(player)
MySessionCallback
işlevini uygulamanızın gerektirdiği şekilde uygulayın. Bu isteğe bağlıdır. Denetleyicilerin oynatıcıya medya öğeleri eklemesine izin vermek istiyorsanızMediaSession.Callback.onAddMediaItems()
uygulayın. Medya öğelerini geriye dönük olarak uyumlu bir şekilde oynatmak üzere oynatıcıya ekleyen çeşitli mevcut ve eski API yöntemlerini sunar. Media3 denetleyicisininMediaController.set/addMediaItems()
yöntemleri ve eski API'ninTransportControls.prepareFrom*/playFrom*
yöntemleri buna dahildir. Örnek bironAddMediaItems
uygulamasını oturum demo uygulamasınınPlaybackService
bölümünde bulabilirsiniz.Taşıma işleminden önce oturumunuzu kaldırdığınız kod sitesinde medya oturumunu yayınlayın:
mediaSession?.run { player.release() release() mediaSession = null }
Media3'te MediaSessionConnector
işlevi
Aşağıdaki tabloda daha önce MediaSessionConnector
ürününde uygulanmış olan işlevleri kullanan Media3 API'leri gösterilmektedir.
MediaSessionConnector | AndroidX Medya |
---|---|
CustomActionProvider |
MediaSession.Callback.onCustomCommand()/
MediaSession.setCustomLayout() |
PlaybackPreparer |
MediaSession.Callback.onAddMediaItems()
(prepare() dahili olarak çağrılır)
|
QueueNavigator |
ForwardingPlayer |
QueueEditor |
MediaSession.Callback.onAddMediaItems() |
RatingCallback |
MediaSession.Callback.onSetRating() |
PlayerNotificationManager |
DefaultMediaNotificationProvider/
MediaNotification.Provider |
MediaBrowserService
adlı kişiyi MediaLibraryService
alanına taşıyın
AndroidX Media3, MediaBrowserServiceCompat
yerine MediaLibraryService
özelliğini kullanıma sunuyor. MediaLibraryService
JavaDoc'u ve MediaSessionService
üst sınıfı, API'ye ve hizmetin eşzamansız programlama modeline iyi bir giriş sağlar.
MediaLibraryService
, MediaBrowserService
ile geriye dönük uyumluluğa sahiptir. MediaBrowserCompat
veya MediaControllerCompat
kullanan bir istemci uygulaması, MediaLibraryService
bağlanırken kod değişikliği olmadan çalışmaya devam eder. İstemci için uygulamanızın MediaLibraryService
veya eski MediaBrowserServiceCompat
kullanması şeffaftır.
Geriye dönük uyumluluğun çalışması için
AndroidManifest.xml
içinde hizmetinize her iki hizmet arayüzünü kaydetmeniz gerekir. Bu şekilde istemci, gerekli hizmet arayüzünden yararlanarak hizmetinizi bulur:<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>
Bağımlılıklarınızı yönettiğiniz
build.gradle
dosyasında, AndroidX Media3 oturum modülüne bir uygulama bağımlılığı ekleyin ve eski bağımlılığı kaldırın:implementation "androidx.media3:media3-session:1.3.1"
MediaBrowserService
yerine hizmetiniziMediaLibraryService
öğesinden devralacak şekilde değiştirin Daha önce de belirtildiği gibi,MediaLibraryService
eskiMediaBrowserService
ile uyumludur. Bu doğrultuda, hizmetin müşterilere sunduğu daha kapsamlı API hâlâ aynı. Bu nedenle, büyük olasılıkla bir uygulama,MediaBrowserService
öğesini uygulamak ve yeniMediaLibraryService
için uyarlamak için gereken mantığın çoğunu koruyabilir.Eski
MediaBrowserServiceCompat
ile karşılaştırıldığında temel farklılıklar aşağıda belirtilmiştir:Hizmet yaşam döngüsü yöntemlerini uygulama: Hizmetin kendisinde geçersiz kılınması gereken yöntemler
onCreate/onDestroy
; bu durumda uygulama, kitaplık oturumunu, oynatıcıyı ve diğer kaynakları ayırır/serbest bırakır. Standart hizmet yaşam döngüsü yöntemlerine ek olarak, bir uygulamanınonCreate
içinde oluşturulanMediaLibrarySession
değerini döndürmek içinonGetSession(MediaSession.ControllerInfo)
değerini geçersiz kılması gerekir.MediaLibraryService.MediaLibrarySessionCallback: Oturum oluşturmak için gerçek alan API yöntemlerini uygulayan bir
MediaLibraryService.MediaLibrarySessionCallback
gereklidir. Dolayısıyla eski hizmetin API yöntemlerini geçersiz kılmak yerineMediaLibrarySession.Callback
yöntemini geçersiz kılarsınız.Geri çağırma, daha sonra
MediaLibrarySession
oluşturmak için kullanılır:mediaLibrarySession = MediaLibrarySession.Builder(this, player, MySessionCallback()) .build()
MediaLibrarySessionCallback'in tam API'sini API belgelerinde bulabilirsiniz.
MediaSession.Callback.onAddMediaItems()
uygulayın: Geri çağırma (onAddMediaItems(MediaSession, ControllerInfo, List<MediaItem>)
), geriye dönük uyumlu olarak oynatılmak üzere oynatıcıya medya öğeleri ekleyen çeşitli mevcut ve eski API yöntemlerini sunar. Media3 denetleyicisininMediaController.set/addMediaItems()
yöntemleri ve eski API'ninTransportControls.prepareFrom*/playFrom*
yöntemleri buna dahildir. Geri çağırmanın örnek uygulamasını oturum demo uygulamasınınPlaybackService
bölümünde bulabilirsiniz.AndroidX Media3, MediaBrowserCompat.MediaItem ve MediaMetadataCompat yerine
androidx.media3.common.MediaItem
kullanır. Kodunuzun eski sınıflara bağlı bazı bölümlerinin uygun şekilde değiştirilmesi veya bunun yerine Media3MediaItem
ile eşlenmesi gerekir.MediaBrowserServiceCompat
'in çıkarılabilirResult
yaklaşımının aksine, genel eşzamansız programlama modeliFutures
olarak değiştirildi. Hizmet uygulamanız, bir sonucu ayırmak yerine eşzamansız birListenableFuture
döndürebilir veya doğrudan bir değer döndürmek için anında bir Gelecek döndürür.
PlayerNotificationManager'ı Kaldır
MediaLibraryService
, medya bildirimlerini otomatik olarak destekler ve PlayerNotificationManager
, MediaLibraryService
veya MediaSessionService
kullanılırken kaldırılabilir.
Bir uygulama, onCreate()
ürününde DefaultMediaNotificationProvider
öğesinin yerine geçen özel bir MediaNotification.Provider
ayarlayarak bildirimi özelleştirebilir. Ardından MediaLibraryService
, hizmetin gerektiği şekilde ön planda başlatılmasını üstlenir.
Bir uygulama MediaLibraryService.updateNotification()
öğesini geçersiz kılarak, bildirim yayınlama ve hizmeti gerektiğinde ön planda başlatma/durdurma konusunda tam sahiplik alabilir.
MediaBrowser kullanarak istemci kodunu taşıma
AndroidX Media3 ile MediaBrowser
, MediaController/Player
arayüzlerini uygular ve medya kitaplığına göz atmanın yanı sıra medya oynatmayı da kontrol etmek için kullanılabilir. Eski dünyada bir MediaBrowserCompat
ve bir MediaControllerCompat
oluşturmanız gerektiyse aynısını yalnızca Media3'te MediaBrowser
kullanarak yapabilirsiniz.
Bir MediaBrowser
derlenebilir ve kurulmakta olan hizmetle bağlantının kurulmasını bekleyebilir:
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)
}
Arka planda oynatmayı kontrol etmek için MediaController
oluşturmayı öğrenmek amacıyla Medya oturumunda oynatmayı kontrol etme bölümüne göz atın.
Daha fazla adım atma ve temizleme
Kararsız API hataları
Media3'e geçiş yaptıktan sonra kararsız API kullanımlarıyla ilgili lint hataları görebilirsiniz.
Bu API'lerin kullanımı güvenlidir ve lint hataları, yeni ikili uyumluluk garantilerimizin yan ürünüdür. Katı ikili program uyumluluğuna ihtiyaç duymuyorsanız bu hatalar @OptIn
ek açıklamasıyla güvenli bir şekilde giderilebilir.
Arka plan
ExoPlayer v1 veya v2, kitaplığın sonraki sürümler arasında ikili program uyumluluğu konusunda kesin garanti vermemiştir. ExoPlayer API yüzeyi, uygulamaların oynatmanın neredeyse her yönünü özelleştirebilmesi için tasarım gereği çok geniştir. ExoPlayer'ın sonraki sürümleri, zaman zaman sembol yeniden adlandırmaları veya zarar veren diğer değişiklikler (ör. arayüzlerde gerekli yeni yöntemler) uygular. Çoğu durumda, geliştiricilerin kullanımlarını taşımaları için zaman tanımak amacıyla eski sembolün kullanımdan kaldırılmasıyla birlikte yeni sembolün kullanıma sunulmasıyla bu bozulmalar azaltılıyordu. Ancak bu her zaman mümkün değildi.
Bu zarar veren değişiklikler, ExoPlayer v1 ve v2 kitaplıklarının kullanıcıları için iki soruna neden oldu:
- ExoPlayer sürümünden yapılan bir yükseltme, kodun derlemeyi durdurmasına neden olabilir.
- Hem doğrudan hem de ara bir kitaplık üzerinden ExoPlayer kullanan bir uygulama, her iki bağımlılığın da aynı sürümde olmasını sağlamak zorundaydı. Aksi takdirde ikili program uyumsuzlukları, çalışma zamanı kilitlenmelerine yol açabilirdi.
Media3'teki İyileştirmeler
Media3, API yüzeyinin bir alt kümesi için ikili uyumluluk garantisi verir. İkili program uyumluluğu garanti edilmeyen parçalar @UnstableApi
ile işaretlenir. Bu ayrımı netleştirmek için kararsız API sembollerinin kullanımı, @OptIn
ile ek açıklama yapılmadığı sürece hata analizi hatası oluşturur.
ExoPlayer v2'den Media3'e geçiş yaptıktan sonra çok sayıda kararsız API lint hatasıyla karşılaşabilirsiniz. Bu durum, Media3'ün ExoPlayer v2'ye göre "daha az kararlı" olmasına neden olabilir. Bu doğru değildir. Media3 API'nin "kararsız" kısımları, ExoPlayer v2 API yüzeyinin tamamıyla aynı kararlılık düzeyine sahiptir ve kararlı Media3 API yüzeyinin garantileri ExoPlayer v2'de hiç yoktur. Aralarındaki fark, bir lint hatasının artık sizi farklı kararlılık seviyeleriyle ilgili olarak uyarmasıdır.
Kararsız API lint hatalarını işleme
Kararsız API lint hatalarını ele almak için iki seçeneğiniz vardır:
- Aynı sonucu elde eden kararlı bir API kullanmaya geçin.
Kararsız API'yi kullanmaya devam edin ve kullanımı
@OptIn
ile not ekleyin.import androidx.annotation.OptIn import androidx.media3.common.util.UnstableApi @OptIn(UnstableApi::class) fun functionUsingUnstableApi() { // Do something useful. }
Kullanılmaması gereken bir
kotlin.OptIn
ek açıklaması da bulunduğunu lütfen unutmayın. Bunun içinandroidx.annotation.OptIn
notuna bağlı kalmak önemlidir.
package-info.java
ekleyerek tüm paketleri etkinleştirebilirsiniz:
@OptIn(markerClass = UnstableApi.class)
package name.of.your.package;
import androidx.annotation.OptIn;
import androidx.media3.common.util.UnstableApi;
lint.xml dosyasındaki belirli lint hatası engellenerek projelerin tamamı dahil edilebilir. Daha fazla ayrıntı için UnstableApi ek açıklamasının JavaDoc'una bakın.
Kullanımdan Kaldırılan API'ler
Android Studio'da, kullanımdan kaldırılmış API'lere yapılan çağrıların üstünün çizildiğini fark edebilirsiniz. Bu tür çağrıları uygun alternatifle değiştirmenizi öneririz. Bunun yerine hangi API'nin kullanılacağını belirten JavaDoc'u görmek için simgenin üzerine gelin.
Kod örnekleri ve demo uygulamaları
- AndroidX Media3 oturumu demo uygulaması (mobil ve WearOS)
- Özel işlemler
- Sistem kullanıcı arayüzü bildirimi, MediaButton/BT
- Google Asistan oynatma kontrolü
- UAMP: Android Media Player (branch media3) (mobil, AutomotiveOS)
- Sistem kullanıcı arayüzü bildirimi, MediaButton/BT, Oynatmayı devam ettirme
- Google Asistan/WearOS oynatma kontrolü
- AutomotiveOS: Özel komut ve oturum açma