راهنمای انتقال AndroidX Media3

برنامه‌هایی که درحال‌حاضر از کتابخانه مستقل com.google.android.exoplayer2 و androidx.media استفاده می‌کنند باید به androidx.media3 منتقل شوند. از اسکریپت انتقال برای انتقال فایل‌های ساخت gradle، فایل‌های منبع جاوا و Kotlin، و فایل‌های چیدمان XML از ExoPlayer 2.19.1 به AndroidX Media3 1.1.1 استفاده کنید.

نمای کلی

قبل‌از انتقال، بخش‌های زیر را مرور کنید تا درباره مزایای میاناهای برنامه‌سازی کاربردی جدید، میاناهای برنامه‌سازی کاربردی برای انتقال، و پیش‌نیازهایی که پروژه برنامه‌تان باید داشته باشد بیشتر بدانید.

چرا باید به Jetpack Media3 مهاجرت کرد

  • این خانه جدید ExoPlayer است، درحالی‌که com.google.android.exoplayer2 متوقف شده است.
  • دسترسی به Player API در سراسر مؤلفه‌ها/فرایندها با MediaBrowser/MediaController.
  • از قابلیت‌های گسترش‌یافته میانای برنامه‌سازی کاربردی MediaSession و MediaController استفاده کنید.
  • قابلیت‌های بازپخش را با کنترل دسترسی دقیق تبلیغ کنید.
  • با برداشتن MediaSessionConnector و PlayerNotificationManager، برنامه‌تان را ساده کنید.
  • سازگار با نسخه‌های قدیمی با میاناهای برنامه‌سازی کاربردی کارخواه media-compat (MediaBrowserCompat/MediaControllerCompat/MediaMetadataCompat)

میاناهای برنامه‌سازی کاربردی رسانه برای انتقال به AndroidX Media3

  • ExoPlayer و افزونه‌های آن
    این شامل همه ماژول‌های پروژه ExoPlayer قدیمی به‌جز ماژول mediasession می‌شود که متوقف شده است. برنامه‌ها یا ماژول‌هایی که به بسته‌های موجود در com.google.android.exoplayer2 وابسته هستند را می‌توان با اسکریپت انتقال منتقل کرد.
  • MediaSessionConnector (بسته به androidx.media.* بسته‌های androidx.media:media:1.4.3+)
    MediaSessionConnector را بردارید و درعوض از androidx.media3.session.MediaSession استفاده کنید.
  • MediaBrowserServiceCompat (بسته به androidx.media.* بسته‌های androidx.media:media:1.4.3+)
    زیرکلاس‌های androidx.media.MediaBrowserServiceCompat را به androidx.media3.session.MediaLibraryService و کد را بااستفاده از MediaBrowserCompat.MediaItem به androidx.media3.common.MediaItem منتقل کنید.
  • MediaBrowserCompat (بسته به android.support.v4.media.* بسته‌های androidx.media:media:1.4.3+)
    کد کارخواه را بااستفاده از MediaBrowserCompat یا MediaControllerCompat انتقال دهید تا از androidx.media3.session.MediaBrowser با androidx.media3.common.MediaItem استفاده کند.

پیش‌نیازها

  1. مطمئن شوید پروژه‌تان تحت کنترل منبع باشد

    مطمئن شوید که می‌توانید تغییرات اعمال‌شده توسط ابزارهای انتقال اسکریپت‌شده را به‌راحتی برگردانید. اگر هنوز پروژه‌تان را تحت کنترل منبع قرار نداده‌اید، اکنون زمان خوبی برای شروع آن است. اگر به هر دلیلی نمی‌خواهید این کار را انجام دهید، قبل‌از شروع انتقال، یک نسخه پشتیبان از پروژه‌تان تهیه کنید.

  2. به‌روزرسانی برنامه

    • توصیه می‌کنیم پروژه‌تان را به‌روز کنید تا از جدیدترین نسخه کتابخانه ExoPlayer استفاده کند و هرگونه فراخوانی روش‌های منسوخ‌شده را بردارید. اگر قصد دارید از دستورگان برای انتقال استفاده کنید، باید نسخه‌ای را که به آن به‌روزرسانی می‌کنید با نسخه‌ای که توسط دستورگان مدیریت می‌شود مطابقت دهید.

    • compileSdkVersion برنامه‌تان را حداقل به ۳۲ افزایش دهید.

    • Gradle و افزایه Android Studio Gradle را به نسخه جدیدی ارتقا دهید که با وابستگی‌های به‌روزشده بالا کار می‌کند. برای مثال:

      • نسخه افزایه Android Gradle: ‏ ۷.۱.۰
      • نسخه Gradle: ‏ ۷.۴
    • همه عبارت‌های وارد کردن با نویسه عام را که از ستاره (*) استفاده می‌کنند جایگزین کنید و از عبارت‌های وارد کردن کاملاً واجدشرایط استفاده کنید: عبارت‌های وارد کردن با نویسه عام را حذف کنید و از Android Studio برای وارد کردن عبارت‌های کاملاً واجدشرایط استفاده کنید (F2 - Alt/Enter،‏ F2 - Alt/Enter،‏ ...).

    • از com.google.android.exoplayer2.PlayerView به com.google.android.exoplayer2.StyledPlayerView منتقل شوید. این کار ضروری است زیرا معادل com.google.android.exoplayer2.PlayerView در AndroidX Media3 وجود ندارد.

انتقال ExoPlayer با پشتیبانی از دستورگان

این دستورگان انتقال از com.google.android.exoplayer2 به ساختار جدید بسته و ماژول را تحت androidx.media3 تسهیل می‌کند. این اسکریپت برخی بررسی‌های اعتبارسنجی را روی پروژه‌تان اعمال می‌کند و اگر اعتبارسنجی ناموفق باشد، هشدارهایی را چاپ می‌کند. درغیراین‌صورت، نگاشت‌های کلاس‌ها و بسته‌های تغییرنام‌یافته را در منابع پروژه gradle Android نوشته‌شده در Java یا 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

استفاده از دستورگان انتقال

  1. اسکریپت انتقال را از برچسب پروژه ExoPlayer در GitHub که با نسخه‌ای که برنامه‌تان را به آن به‌روز کرده‌اید مطابقت دارد بارگیری کنید:

    curl -o media3-migration.sh \
      "https://raw.githubusercontent.com/google/ExoPlayer/r2.19.1/media3-migration.sh"
    
  2. متن را قابل‌اجرا کنید:

    chmod 744 media3-migration.sh
    
  3. برای آشنایی با گزینه‌ها، دستورات را با --help اجرا کنید.

  4. اسکریپت را با -l اجرا کنید تا مجموعه فایل‌های انتخاب‌شده برای انتقال فهرست شود (از -f برای اجبار به فهرست کردن بدون هشدار استفاده کنید):

    ./media3-migration.sh -l -f /path/to/gradle/project/root
    
  5. اسکریپت را با -m اجرا کنید تا بسته‌ها، کلاس‌ها، و ماژول‌ها را به Media3 نگاشت کنید. اجرای دستورگان با گزینه -m تغییرات را در فایل‌های انتخاب‌شده اعمال خواهد کرد.

    • توقف در خطای اعتبارسنجی بدون اعمال تغییرات
    ./media3-migration.sh -m /path/to/gradle/project/root
    
    • اجرای اجباری

    اگر اسکریپت نقض پیش‌نیازها را پیدا کند، می‌توان انتقال را با پرچم -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

پس‌از اجرای اسکریپت با گزینه -m، این مراحل دستی را تکمیل کنید:

  1. بررسی کنید که اسکریپت چگونه کد شما را تغییر داده است: از ابزار diff استفاده کنید و مشکلات احتمالی را برطرف کنید (اگر فکر می‌کنید اسکریپت مشکل کلی دارد که بدون گذراندن گزینه -f معرفی شده است، یک اشکال ثبت کنید).
  2. ساختن پروژه: از ./gradlew clean build استفاده کنید یا در «استودیو Android» فایل > همگام‌سازی پروژه با فایل‌های Gradle، سپس ساختن > پاک کردن پروژه، و سپس ساختن > بازساختن پروژه را انتخاب کنید (ساختن خود را در برگه «ساختن - خروجی ساختن» در «استودیو Android» پایش کنید).

مراحل پیگیری توصیه‌شده:

  1. موافقت کردن با خطاهای مربوط به استفاده از میاناهای برنامه‌سازی کاربردی ناپایدار را حل کنید.
  2. جایگزین کردن فراخوانی‌های API منسوخ‌شده: از API جایگزین پیشنهادی استفاده کنید. اشاره‌گر را روی هشدار در «استودیو Android» نگه دارید و با JavaDoc نماد منسوخ‌شده مشورت کنید تا متوجه شوید به‌جای تماس داده‌شده از چه چیزی استفاده کنید.
  3. مرتب‌سازی دستورهای وارد کردن: پروژه را در «استودیو Android» باز کنید، سپس روی گره پوشه بسته در نمایشگر پروژه کلیک راست کنید و بهینه‌سازی وارد کردن‌ها را در بسته‌هایی که حاوی فایل‌های منبع تغییریافته هستند انتخاب کنید.

MediaSessionConnector را با androidx.media3.session.MediaSession جایگزین کنید

در دنیای قدیمی MediaSessionCompat، MediaSessionConnector مسئول همگام‌سازی وضعیت پخش‌کننده با وضعیت جلسه و دریافت فرمان‌ها از کنترل‌کننده‌هایی بود که نیاز به واگذاری به روش‌های مناسب پخش‌کننده داشتند. با AndroidX Media3، این کار مستقیماً توسط MediaSession بدون نیاز به اتصال‌دهنده انجام می‌شود.

  1. همه ارجاع‌ها و موارد استفاده از MediaSessionConnector را بردارید: اگر از اسکریپت خودکار برای انتقال کلاس‌ها و بسته‌های ExoPlayer استفاده کرده‌اید، احتمالاً اسکریپت کد شما را در وضعیت غیرقابل‌کامپایل کردن دررابطه‌با MediaSessionConnector که قابل‌حل نیست رها کرده است. وقتی می‌خواهید برنامه را بسازید یا شروع کنید، Android Studio کد خراب را به شما نشان می‌دهد.

  2. در فایل build.gradle که وابستگی‌هایتان را در آن نگهداری می‌کنید، یک وابستگی پیاده‌سازی به ماژول جلسه AndroidX Media3 اضافه کنید و وابستگی قدیمی را بردارید:

    implementation "androidx.media3:media3-session:1.11.1"
    
  3. MediaSessionCompat را با androidx.media3.session.MediaSession جایگزین کنید.

  4. در سایت کدی که MediaSessionCompat قدیمی را ایجاد کرده‌اید، از androidx.media3.session.MediaSession.Builder برای ساختن MediaSession استفاده کنید. پخش‌کننده را ارسال کنید تا سازنده جلسه ساخته شود.

    کاتلین

    val player = ExoPlayer.Builder(context).build()
    mediaSession = MediaSession.Builder(context, player).setCallback(MySessionCallback()).build()

    جاوا

    ExoPlayer player = new ExoPlayer.Builder(context).build();
    mediaSession =
        new MediaSession.Builder(context, player).setCallback(new MySessionCallback()).build();

  5. MySessionCallback را طبق نیاز برنامه‌تان پیاده‌سازی کنید. این کار اختیاری است. اگر می‌خواهید به کنترل‌کننده‌ها اجازه دهید موارد رسانه‌ای را به پخش‌کننده اضافه کنند، MediaSession.Callback.onAddMediaItems() را پیاده‌سازی کنید. این کلاس روش‌های مختلف فعلی و قدیمی میانای برنامه‌سازی کاربردی را ارائه می‌دهد که موارد رسانه‌ای را برای بازپخش به روشی سازگار با نسخه‌های قدیمی به پخش‌کننده اضافه می‌کنند. این شامل روش‌های MediaController.set/addMediaItems() کنترل‌کننده Media3 و همچنین روش‌های TransportControls.prepareFrom*/playFrom* میانای برنامه‌سازی کاربردی قدیمی می‌شود. نمونه‌ای از پیاده‌سازی onAddMediaItems را می‌توانید در PlaybackService برنامه نمایشی جلسه پیدا کنید.

  6. جلسه رسانه را در سایت کد که در آن جلسه را قبل‌از انتقال ازبین بردید، منتشر کنید:

    کاتلین

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

    جاوا

    if (mediaSession != null) {
      mediaSession.getPlayer().release();
      mediaSession.release();
      mediaSession = null;
    }

عملکرد MediaSessionConnector در Media3

جدول زیر میاناهای برنامه‌سازی کاربردی Media3 را نشان می‌دهد که عملکردی را که قبلاً در MediaSessionConnector پیاده‌سازی شده بود مدیریت می‌کنند.

MediaSessionConnectorAndroidX Media3
CustomActionProvider MediaSession.Callback.onCustomCommand()/ MediaSession.setMediaButtonPreferences()
PlaybackPreparer MediaSession.Callback.onAddMediaItems() (prepare() به‌صورت داخلی فراخوانی می‌شود)
QueueNavigator ForwardingSimpleBasePlayer
QueueEditor MediaSession.Callback.onAddMediaItems()
RatingCallback MediaSession.Callback.onSetRating()
PlayerNotificationManager DefaultMediaNotificationProvider/ MediaNotification.Provider

انتقال MediaBrowserService به MediaLibraryService

AndroidX Media3‏ MediaLibraryService را معرفی می‌کند که جایگزین MediaBrowserServiceCompat می‌شود. JavaDoc مربوط به MediaLibraryService و کلاس فوق‌العاده آن MediaSessionService مقدمه خوبی برای API و مدل برنامه‌نویسی ناهمگام سرویس ارائه می‌دهد.

MediaLibraryService با MediaBrowserService سازگار با نسخه قدیمی است. برنامه کارخواهی که از MediaBrowserCompat یا MediaControllerCompat استفاده می‌کند، هنگام اتصال به MediaLibraryService بدون تغییر کد به کار خود ادامه می‌دهد. برای مشتری، شفاف است که برنامه شما از MediaLibraryService استفاده می‌کند یا از MediaBrowserServiceCompat قدیمی.

نمودار مؤلفه برنامه با سرویس، فعالیت، و برنامه‌های خارجی.
شکل ۱: نمای کلی مؤلفه برنامه رسانه
  1. برای اینکه سازگاری با نسخه قدیمی کار کند، باید هر دو میانای سرویس را با سرویس خود در AndroidManifest.xml ثبت کنید. به این ترتیب، کارخواه سرویس شما را ازطریق میانای سرویس موردنیاز پیدا می‌کند:

    <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. در فایل build.gradle که وابستگی‌هایتان را در آن نگهداری می‌کنید، یک وابستگی پیاده‌سازی به واحد جلسه AndroidX Media3 اضافه کنید و وابستگی قدیمی را بردارید:

    implementation "androidx.media3:media3-session:1.11.1"
    
  3. سرویس خود را تغییر دهید تا به‌جای MediaBrowserService از MediaLibraryService ارث‌بری کند. همان‌طور که قبلاً گفته شد، MediaLibraryService با MediaBrowserService قدیمی سازگار است. بنابراین، میانای برنامه‌سازی کاربردی گسترده‌تری که سرویس به کارخواهان ارائه می‌دهد همچنان یکسان است. بنابراین احتمالاً برنامه می‌تواند بیشتر منطق لازم برای پیاده‌سازی MediaBrowserService را حفظ کند و آن را برای MediaLibraryService جدید تطبیق دهد.

    تفاوت‌های اصلی در مقایسه با MediaBrowserServiceCompat قدیمی به شرح زیر است:

    • پیاده‌سازی روش‌های چرخه عمر سرویس: روش‌هایی که باید در خود سرویس لغو شوند عبارتند از onCreate/onDestroy، که در آن برنامه جلسه کتابخانه، پخش‌کننده، و سایر منابع را اختصاص می‌دهد/آزاد می‌کند. علاوه‌بر روش‌های استاندارد چرخه عمر سرویس، برنامه باید onGetSession(MediaSession.ControllerInfo) را لغو کند تا MediaLibrarySession ساخته‌شده در onCreate را برگرداند.

    • پیاده‌سازی MediaLibraryService.MediaLibrarySessionCallback: ساختن جلسه به MediaLibraryService.MediaLibrarySessionCallback نیاز دارد که روش‌های میانای برنامه‌سازی کاربردی دامنه واقعی را پیاده‌سازی می‌کند. بنابراین به‌جای لغو کردن روش‌های میانای برنامه‌سازی کاربردی سرویس قدیمی، روش‌های MediaLibrarySession.Callback را لغو خواهید کرد.

      سپس از فراخوانی برگشتی برای ساختن MediaLibrarySession استفاده می‌شود:

      کاتلین

      mediaLibrarySession = MediaLibrarySession.Builder(context, player, MySessionCallback()).build()

      جاوا

      mediaLibrarySession =
          new MediaLibrarySession.Builder(context, player, new MySessionCallback()).build();

      میانای برنامه‌سازی کاربردی کامل MediaLibrarySessionCallback را در اسناد میانای برنامه‌سازی کاربردی پیدا کنید.

    • پیاده‌سازی MediaSession.Callback.onAddMediaItems(): فراخوانی برگشتی onAddMediaItems(MediaSession, ControllerInfo, List<MediaItem>) روش‌های مختلف میانای برنامه‌سازی کاربردی فعلی و قدیمی را که موارد رسانه‌ای را برای بازپخش به روش سازگار با نسخه‌های قدیمی به پخش‌کننده اضافه می‌کنند ارائه می‌دهد. این شامل روش‌های MediaController.set/addMediaItems() کنترل‌کننده Media3، و همچنین روش‌های TransportControls.prepareFrom*/playFrom* میانای برنامه‌سازی کاربردی قدیمی می‌شود. نمونه‌ای از پیاده‌سازی callback را می‌توانید در PlaybackService برنامه نمایشی جلسه پیدا کنید.

    • AndroidX Media3 به‌جای MediaBrowserCompat.MediaItem و MediaMetadataCompat از androidx.media3.common.MediaItem استفاده می‌کند. بخش‌هایی از کد شما که به کلاس‌های قدیمی مرتبط است باید به‌طور مناسب تغییر کند یا به‌جای آن به Media3 MediaItem نگاشت شود.

    • مدل برنامه‌نویسی ناهمگام عمومی به Futures تغییر کرد، برخلاف رویکرد Result جداشدنی MediaBrowserServiceCompat. پیاده‌سازی سرویس شما می‌تواند به‌جای جدا کردن نتیجه، ListenableFuture ناهمگام برگرداند یا برای برگرداندن مستقیم مقدار، Future فوری برگرداند.

برداشتن PlayerNotificationManager

MediaLibraryService به‌طور خودکار از اعلان‌های رسانه پشتیبانی می‌کند و PlayerNotificationManager را می‌توان هنگام استفاده از MediaLibraryService یا MediaSessionService برداشت.

برنامه می‌تواند با تنظیم MediaNotification.Provider سفارشی در onCreate() که جایگزین DefaultMediaNotificationProvider می‌شود، اعلان را سفارشی‌سازی کند. سپس MediaLibraryService شروع سرویس در پیش‌نما را طبق نیاز انجام می‌دهد.

با لغو کردن MediaLibraryService.updateNotification()، برنامه می‌تواند مالکیت کامل پست کردن اعلان و شروع/توقف سرویس در پیش‌زمینه را درصورت نیاز به‌دست آورد.

انتقال کد کارخواه بااستفاده از MediaBrowser

با AndroidX Media3، یک MediaBrowser میاناهای MediaController/Player را پیاده‌سازی می‌کند و می‌تواند برای کنترل بازپخش رسانه علاوه‌بر مرور کتابخانه رسانه استفاده شود. اگر مجبور بودید MediaBrowserCompat و MediaControllerCompat را در دنیای قدیمی ایجاد کنید، می‌توانید همین کار را فقط بااستفاده از MediaBrowser در Media3 انجام دهید.

می‌توان MediaBrowser را ساخت و منتظر برقراری اتصال به سرویس ماند:

کاتلین

scope.launch {
  val sessionToken = SessionToken(context, ComponentName(context, "MusicService"))
  browser =
    MediaBrowser.Builder(context, sessionToken)
      .setListener(BrowserListener())
      .buildAsync()
      .await()
}

جاوا

SessionToken sessionToken =
    new SessionToken(context, new ComponentName(context, "MusicService"));
ListenableFuture<MediaBrowser> browserFuture =
    new MediaBrowser.Builder(context, sessionToken)
        .setListener(new BrowserListener())
        .buildAsync();

به کنترل بازپخش در جلسه رسانه نگاهی بیندازید تا با نحوه ایجاد MediaController برای کنترل بازپخش در پس‌زمینه آشنا شوید.

مراحل بعدی و پاک‌سازی

خطاهای میانای برنامه‌سازی کاربردی ناپایدار

پس‌از انتقال به Media3، ممکن است خطاهای lint درباره استفاده‌های ناپایدار از API ببینید. استفاده از این میاناهای برنامه‌سازی کاربردی ایمن است و خطاهای lint محصول جانبی تضمین‌های جدید سازگاری دودویی ما است. اگر به سازگاری دودویی دقیق نیاز ندارید، می‌توانید این خطاها را با حاشیه‌نویسی @OptIn به‌طور ایمن سرکوب کنید.

پس‌زمینه

هیچ‌کدام از ExoPlayer نسخه ۱ یا ۲ تضمین‌های دقیقی درباره سازگاری دودویی کتابخانه بین نسخه‌های بعدی ارائه نمی‌دهند. سطح ExoPlayer API به‌طور عمدی بسیار بزرگ طراحی شده است تا برنامه‌ها بتوانند تقریباً هر جنبه‌ای از بازپخش را سفارشی‌سازی کنند. نسخه‌های بعدی ExoPlayer گاهی اوقات تغییر نام نماد یا تغییرات شکننده دیگری را معرفی می‌کنند (مثلاً روش‌های جدید موردنیاز در میاناهای کاربری). در بیشتر موارد، این شکستگی‌ها با معرفی نماد جدید در کنار منسوخ کردن نماد قدیمی برای چند نسخه کاهش یافت تا توسعه‌دهندگان زمان کافی برای انتقال استفاده‌های خود داشته باشند، اما این امر همیشه ممکن نبود.

این تغییرات ناسازگار منجر به دو مشکل برای کاربران کتابخانه‌های ExoPlayer نسخه ۱ و ۲ شد:

  1. ارتقا دادن به نسخه ExoPlayer می‌تواند باعث شود کد کامپایل نشود.
  2. برنامه‌ای که هم به‌طور مستقیم و هم ازطریق کتابخانه واسطه به ExoPlayer وابسته بود، باید مطمئن می‌شد که هر دو وابستگی از یک نسخه هستند، درغیراین‌صورت ناسازگاری‌های دودویی می‌توانست منجر به ازکارافتادن زمان اجرا شود.

بهبودهای Media3

Media3 سازگاری دودویی را برای زیرمجموعه‌ای از سطح میانای برنامه‌سازی کاربردی تضمین می‌کند. بخش‌هایی که سازگاری دودویی را تضمین نمی‌کنند با @UnstableApi علامت‌گذاری شده‌اند. برای روشن کردن این تمایز، استفاده از نمادهای ناپایدار میانای برنامه‌سازی کاربردی خطای lint ایجاد می‌کند، مگراینکه با @OptIn حاشیه‌نویسی شده باشند.

پس‌از انتقال از ExoPlayer نسخه ۲ به Media3، ممکن است خطاهای lint زیادی در API ناپایدار مشاهده کنید. این ممکن است باعث شود Media3 «پایداری کمتری» نسبت‌به ExoPlayer نسخه ۲ داشته باشد. این‌طور نیست. بخش‌های «ناپایدار» Media3 API همان سطح پایداری را دارند که کل سطح ExoPlayer v2 API دارد، و تضمین‌های سطح Media3 API پایدار اصلاً در ExoPlayer v2 دردسترس نیست. تفاوت به‌سادگی این است که خطای lint اکنون شما را از سطوح مختلف پایداری مطلع می‌کند.

رسیدگی به خطاهای lint میانای برنامه‌سازی کاربردی ناپایدار

برای جزئیات بیشتر درباره نحوه حاشیه‌نویسی کاربردهای Java و Kotlin از میاناهای برنامه‌سازی کاربردی ناپایدار با @OptIn، به بخش عیب‌یابی مربوط به این خطاهای lint مراجعه کنید.

میاناهای برنامه‌سازی کاربردی منسوخ‌شده

ممکن است متوجه شوید که فراخوانی‌های میاناهای برنامه‌سازی کاربردی منسوخ‌شده در Android Studio خط‌خورده‌اند. توصیه می‌کنیم این فراخوانی‌ها را با جایگزین مناسب عوض کنید. نشانگر را روی نماد نگه دارید تا JavaDoc را ببینید که می‌گوید به‌جای آن از کدام API استفاده کنید.

نماگرفت: نحوه نمایش JavaDoc با جایگزین روش منسوخ‌شده
شکل ۳: نکته‌ابزار JavaDoc در «استودیو Android» جایگزینی برای هر نماد منسوخ‌شده پیشنهاد می‌کند.

نمونه‌های کد و برنامه‌های نمایشی

  • برنامه نمایشی جلسه AndroidX Media3 (تلفن همراه و WearOS)
    • کنش‌های سفارشی
    • اعلان واسط کاربر سیستم، MediaButton/BT
    • کنترل بازپخش «دستیار Google»
  • UAMP: Android Media Player (branch media3) (mobile, AutomotiveOS)
    • اعلان واسط کاربری سیستم، MediaButton/BT، ازسرگیری بازپخش
    • کنترل بازپخش «دستیار Google»/ WearOS
    • AutomotiveOS: فرمان سفارشی و ورود به سیستم