AndroidX Media3 taşıma kılavuzu

Şu anda bağımsız com.google.android.exoplayer2 kitaplığını ve androidx.media kitaplığını kullanan uygulamalar androidx.media3 hedefine taşınmalıdır. Gradle derleme dosyalarını, Java ve Kotlin kaynak dosyalarını ve XML düzen dosyalarını ExoPlayer 2.19.1'den 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 uygulama projenizin 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?

  • ExoPlayer'ın yeni adresidir. 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 ve MediaController API'nin gelişmiş özelliklerini kullanın.
  • Ayrıntılı erişim denetimi ile oynatma özelliklerinin reklamını yapın.
  • MediaSessionConnector ve PlayerNotificationManager öğelerini kaldırarak uygulamanızı basitleştirin.
  • Medya uyumlu istemci API'leriyle geriye dönük uyumlu (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 hizmetindeki paketlere bağlı olarak uygulamalar veya modüller, taşıma komut dosyasıyla taşınabilir.
  • MediaSessionConnector (androidx.media:media:1.4.3+ paketinin androidx.media.* paketine bağlı olarak)
    MediaSessionConnector öğesini kaldırın ve onun yerine androidx.media3.session.MediaSession kullanın.
  • MediaTarayıcıServiceCompat (androidx.media:media:1.4.3+ paketinin androidx.media.* paketine bağlı olarak)
    androidx.media.MediaBrowserServiceCompat alt sınıflarını androidx.media3.session.MediaLibraryService öğesine ve kodları MediaBrowserCompat.MediaItem kullanarak androidx.media3.common.MediaItem öğesine taşıyın.
  • MediaTarayıcıCompat (androidx.media:media:1.4.3+ paketinin android.support.v4.media.* paketine bağlı olarak)
    androidx.media3.session.MediaBrowser öğesini androidx.media3.common.MediaItem ile kullanmak için MediaBrowserCompat veyaMediaControllerCompat kullanarak istemci kodunu taşıyın.

Ön koşullar

  1. Projenizin kaynak kontrolü altında olduğundan emin olma

    Komut dosyası tabanlı taşıma araçları tarafından uygulanan değişiklikleri kolayca geri döndürebileceğinizden emin olun. Projeniz henüz kaynak denetimi altında değilse projeye başlamanın tam zamanı. Herhangi bir nedenle bunu yapmak istemezseniz taşıma işlemine başlamadan önce projenizin yedek kopyasını oluşturun.

  2. 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şleminde 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 derlemeSdkVersion değerini en az 32'ye yükseltin.

    • Gradle ve Android Studio Gradle eklentisini yukarıdaki güncellenmiş bağımlılıklarla çalışan yeni bir sürüme yükseltin. Örneğin:

      • Android Gradle Eklentisi sürümü: 7.1.0
      • Gradle sürümü: 7.4
    • Yıldız işareti (*) kullanan ve tam nitelikli içe aktarma ifadeleri kullanan tüm joker karakter içe aktarma ifadelerini değiştirin: 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 - com.google.android.exoplayer2.StyledPlayerView arasında geçiş yapın. AndroidX Media3'te com.google.android.exoplayer2.PlayerView öğesinin eşdeğeri olmadığından bu gereklidir.

Komut dosyası desteğiyle ExoPlayer'ı taşıyın

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ı, projenizde 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ına 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

  1. GitHub'da, uygulamanızı güncellediğiniz sürüme karşılık gelen ExoPlayer projesinin etiketinden taşıma komut dosyasını indirin:

    curl -o media3-migration.sh \
      "https://raw.githubusercontent.com/google/ExoPlayer/r2.19.1/media3-migration.sh"
    
  2. Komut dosyasını yürütülebilir hale getirin:

    chmod 744 media3-migration.sh
    
  3. Seçenekler hakkında bilgi edinmek için komut dosyasını --help ile çalıştırın.

  4. Taşıma için seçilen dosya grubunu listelemek amacıyla komut dosyasını -l ile çalıştırın (girişi uyarı olmadan zorunlu kılmak için -f kullanın):

    ./media3-migration.sh -l -f /path/to/gradle/project/root
    
  5. 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çilen dosyalara uygulanır.

    • Değişiklik yapmadan doğrulama hatasında durdurun
    ./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 zorlanabilir:

    ./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:

  1. 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ında -f seçeneği iletilmeden ortaya çıkan genel bir sorun olduğunu düşünüyorsanız hata bildiriminde bulunun).
  2. Projeyi derleme: ./gradlew clean build komutunu kullanın veya Android Studio'da Dosya > Projeyi Gradle Dosyalarıyla Senkronize Et'i, Derle > Projeyi temizle'yi ve ardından Derle > Projeyi yeniden oluştur'u seçin (derlemenizi Android Studio'nun "Derleme - Derleme Çıkışı" sekmesinde izleyin).

Önerilen takip adımları:

  1. Kararsız API'lerin kullanımıyla ilgili hatalar için kaydolma sorununu çözün.
  2. Desteği sonlandırılan API çağrılarını değiştirin: Önerilen yedek API'yi kullanın. İşaretçiyi Android Studio'da uyarının üzerinde tutun ve belirli bir çağrı yerine ne kullanılacağını öğrenmek için desteği sonlandırılan simgenin JavaDoc'una bakın.
  3. İç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 yazın

Eski MediaSessionCompat dünyasında MediaSessionConnector, oynatıcının durumunu oturumun durumuyla senkronize etmekten ve denetleyicilerden, uygun oynatıcı yöntemleri için yetki verilmesi gereken komutları almaktan sorumluydu. AndroidX Media3'te bu işlem, bağlayıcı gerekmeden doğrudan MediaSession tarafından yapılır.

  1. 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ümlenemeyenMediaSessionConnector ile ilgili olarak derlenemez durumda bırakmıştır. Android Studio, uygulamayı derlemeye veya başlatmaya çalıştığınızda bozuk kodu gösterir.

  2. Bağımlılıklarınızı yönettiğiniz build.gradle dosyasına 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"
    
  3. MediaSessionCompat değerini androidx.media3.session.MediaSession ile değiştirin.

  4. Eski MediaSessionCompat kodunu oluşturduğunuz kod sitesinde, bir MediaSession oluşturmak için androidx.media3.session.MediaSession.Builder komutunu 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()
    
  5. MySessionCallback özelliğini 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ız MediaSession.Callback.onAddMediaItems() kodunu uygulayın. Geriye dönük uyumlu bir şekilde oynatma için oynatıcıya medya öğeleri ekleyen çeşitli mevcut ve eski API yöntemlerini sunar. Buna Media3 denetleyicisinin MediaController.set/addMediaItems() yöntemlerinin yanı sıra eski API'nin TransportControls.prepareFrom*/playFrom* yöntemleri de dahildir. onAddMediaItems örneğinin bir kullanımını oturum demo uygulamasının PlaybackService bölümünde bulabilirsiniz.

  6. Taşıma işleminden önce, oturumunuzu kaldırdığınız kod sitesinde medya oturumunu serbest bırakın:

    mediaSession?.run {
      player.release()
      release()
      mediaSession = null
    }
    

Medya3'te MediaSessionConnector işlevi

Aşağıdaki tabloda, daha önce MediaSessionConnector ürününde uygulanmış olan işlevleri gerçekleştiren Media3 API'leri gösterilmektedir.

MediaSessionConnectorAndroidX Medya 3
CustomActionProvider MediaSession.Callback.onCustomCommand()/ MediaSession.setCustomLayout()
PlaybackPreparer MediaSession.Callback.onAddMediaItems() (prepare() dahili olarak çağrılıyor)
QueueNavigator ForwardingPlayer
QueueEditor MediaSession.Callback.onAddMediaItems()
RatingCallback MediaSession.Callback.onSetRating()
PlayerNotificationManager DefaultMediaNotificationProvider/ MediaNotification.Provider

MediaBrowserService alanını MediaLibraryService kuruluşuna taşıyın

AndroidX Media3, MediaBrowserServiceCompat yerine MediaLibraryService ürününü kullanıma sundu. MediaLibraryService JavaDoc'u ve üst sınıfı MediaSessionService, hizmetin eşzamansız programlama modeline ve API'ye iyi bir giriş yapar.

MediaLibraryService, MediaBrowserService ile geriye dönük uyumludur. MediaBrowserCompat veya MediaControllerCompat kullanan bir istemci uygulaması, MediaLibraryService cihazına bağlanırken kod değişikliği olmadan çalışmaya devam ediyor. İstemciler için, uygulamanızın MediaLibraryService mi yoksa eski MediaBrowserServiceCompat mi kullandığı şeffaftır.

Hizmet, etkinlik ve harici uygulamaları içeren uygulama bileşeni diyagramı.
Şekil 1: Medya uygulaması bileşenine genel bakış
  1. Geriye dönük uyumluluğun çalışması için her iki hizmet arayüzünü de AndroidManifest.xml içinde hizmetinize kaydetmeniz gerekir. Bu şekilde müşteri, hizmetinizi gerekli hizmet arayüzü aracılığıyla 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>
    
  2. 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"
    
  3. Hizmetinizi MediaBrowserService yerine bir MediaLibraryService öğesinden devralacak şekilde değiştirin Daha önce de belirtildiği gibi, MediaLibraryService eski MediaBrowserService ile uyumludur. Buna göre, hizmetin müşterilere sunduğu daha kapsamlı API hâlâ aynı. Dolayısıyla bir uygulama, MediaBrowserService öğesini uygulamak için gerekli mantığın çoğunu koruyabilir ve bunu yeni MediaLibraryService ürününe uyarlayabilir.

    Eski MediaBrowserServiceCompat ile karşılaştırıldığında temel farklar şunlardır:

    • Hizmet yaşam döngüsü yöntemlerini uygulayın: Hizmetin kendisinde geçersiz kılınması gereken yöntemler onCreate/onDestroy'dır. Bu yöntemde uygulama; kitaplık oturumunu, oynatıcıyı ve diğer kaynakları ayırır/yayınlar. Standart hizmet yaşam döngüsü yöntemlerine ek olarak, bir uygulamanın onCreate ürününde yerleşik olarak bulunan MediaLibrarySession öğesini döndürebilmesi için onGetSession(MediaSession.ControllerInfo) öğesini geçersiz kılması gerekir.

    • MediaLibraryService.MediaLibrarySessionCallback: Oturum oluşturmak, gerçek alan API yöntemlerini uygulayan bir MediaLibraryService.MediaLibrarySessionCallback gerektirir. Dolayısıyla, eski hizmetin API yöntemlerini geçersiz kılmak yerine MediaLibrarySession.Callback yöntemini geçersiz kılarsınız.

      Daha sonra geri çağırma işlevi 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>), medya öğelerini geriye dönük olarak uyumlu bir şekilde oynatmak için oynatıcıya ekleyen çeşitli mevcut ve eski API yöntemlerini sunar. Buna Media3 denetleyicisinin MediaController.set/addMediaItems() yöntemlerinin yanı sıra eski API'nin TransportControls.prepareFrom*/playFrom* yöntemleri de dahildir. Geri çağırmanın örnek bir uygulamasını oturum demo uygulamasının PlaybackService sayfasında bulabilirsiniz.

    • AndroidX Media3, MediaTarayıcıCompat.MediaItem ve MediaMetadataCompat yerine androidx.media3.common.MediaItem kullanıyor. Kodunuzun eski sınıflara bağlı bölümlerinin uygun şekilde değiştirilmesi veya Media3 MediaItem ile eşlenmesi gerekir.

    • MediaBrowserServiceCompat'nin çıkarılabilir Result yaklaşımının aksine, genel eşzamansız programlama modeli Futures olarak değiştirildi. Hizmet uygulamanız, bir sonucu çıkarmak yerine eşzamansız bir ListenableFuture döndürebilir veya doğrudan bir değer döndürmek için yakın bir Gelecek döndürebilir.

PlayerBildirim Yöneticisini Kaldır

MediaLibraryService, medya bildirimlerini otomatik olarak destekler ve MediaLibraryService veya MediaSessionService kullanılırken PlayerNotificationManager kaldırılabilir.

Bir uygulama, onCreate() ürününde DefaultMediaNotificationProvider öğesinin yerini alan özel bir MediaNotification.Provider ayarlayarak bildirimi özelleştirebilir. Daha sonra MediaLibraryService, gerektiği şekilde hizmetin ön planda başlatılmasını sağlar.

MediaLibraryService.updateNotification() geçersiz kılındığında bir uygulama, bildirim yayınlama ve hizmeti ön planda başlatma/durdurma konusunda tam sahiplik elde edebilir.

MediaTarayıcı kullanarak istemci kodunu taşıma

AndroidX Media3 ile bir MediaBrowser, MediaController/Player arayüzlerini uygular ve medya kitaplığına göz atmanın yanı sıra medya oynatmayı kontrol etmek için de kullanılabilir. Eski dünyada hem MediaBrowserCompat hem de MediaControllerCompat oluşturmanız gerekiyorsa aynı işlemi yalnızca Media3'teki MediaBrowser öğesini kullanarak yapabilirsiniz.

Bir MediaBrowser oluşturulabilir ve oluşturulan hizmetle bağlantının kurulmasını bekleyebilirsiniz:

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 üzere nasıl MediaController oluşturacağınızı öğrenmek için Medya oturumunda oynatmayı kontrol etme bölümüne göz atın.

Daha fazla işlem yapın ve yer açın

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 bir yan ürünüdür. Katı ikili uyumluluğu gerekmiyorsa bu hatalar bir @OptIn ek açıklamasıyla güvenli bir şekilde bastırılabilir.

Arka plan

ExoPlayer v1 veya v2, kitaplığın sonraki sürümler arasında ikili program uyumluluğuna ilişkin katı garantiler vermemiştir. ExoPlayer API yüzeyi, uygulamaların oynatmanın neredeyse her yönünü özelleştirmesine olanak tanımak için tasarım gereği çok büyüktür. ExoPlayer'ın sonraki sürümleri, zaman zaman sembol yeniden adlarını veya zarar veren diğer değişiklikleri (ör. arayüzlerde yeni gerekli yöntemler) kullanıma sunar. Çoğu durumda bu kesintiler, yeni simgenin kullanıma sunulması ve birkaç sürümde eski simgenin kullanımdan kaldırılmasıyla azaltılarak geliştiricilere kullanımlarını taşımaları için zaman tanımakla birlikte bu durum her zaman mümkün olmuyordu.

Bu zarar veren değişiklikler, ExoPlayer v1 ve v2 kitaplıkları kullanıcıları için iki soruna yol açmıştır:

  1. ExoPlayer sürümüne yükseltme yapmak kodun derlemeyi durdurmasına neden olabilir.
  2. Hem doğrudan hem de ara bir kitaplık aracılığıyla ExoPlayer'a dayanan bir uygulama, her iki bağımlının da aynı sürümde olmasını sağlamak zorundaydı. Aksi takdirde, ikili program uyumsuzlukları çalışma zamanı kilitlenmelerine neden olabilirdi.

Media3'teki İyileştirmeler

Media3, API yüzeyinin bir alt kümesi için ikili program uyumluluğunu garanti eder. İkili program uyumluluğunu garanti etmeyen bölümler @UnstableApi ile işaretlenmiştir. Bu ayrımı netleştirmek amacıyla, kararsız API simgelerinin kullanımları, @OptIn ile ek açıklama eklenmedikçe lint 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'den "daha az kararlı" görünmesine neden olabilir. Böyle bir durum söz konusu değildir. Media3 API'nin "kararsız" bölümleri, ExoPlayer v2 API yüzeyinin tümüyle aynı istikrar düzeyine sahiptir ve kararlı Media3 API yüzeyinin garantileri ExoPlayer v2'de hiçbir şekilde geçerli değildir. Aradaki fark, lint hatasının artık sizi farklı kararlılık düzeyleri hakkında uyarmasıdır.

Kararsız API lint hatalarını işleme

Kararsız API'lerin Java ve Kotlin kullanımlarına @OptIn ile nasıl ek açıklama yapılacağı hakkında ayrıntılı bilgi için bu lint hatalarıyla ilgili sorun giderme bölümüne bakın.

Desteği sonlandırılmış API'ler

Kullanımdan kaldırılan API'lere yapılan çağrıların Android Studio'da belirdiğ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 fareyle simgenin üzerine gelin.

Ekran görüntüsü: JavaDoc&#39;u kullanımdan kaldırılmış alternatif bir yöntemle görüntüleme
Şekil 3: Android Studio'daki JavaDoc ipucu, kullanımdan kaldırılan simgeler için bir alternatif önerir.

Kod örnekleri ve demo uygulamaları