Các ứng dụng hiện đang sử dụng thư viện com.google.android.exoplayer2
và androidx.media
độc lập cần di chuyển sang androidx.media3
. Sử dụng tập lệnh di chuyển để di chuyển các tệp bản dựng gradle, tệp nguồn Java và Kotlin, cũng như tệp bố cục XML từ ExoPlayer 2.19.1
sang AndroidX Media3 1.1.1
.
Tổng quan
Trước khi di chuyển, hãy xem các phần sau để tìm hiểu thêm về lợi ích của các API mới, API cần di chuyển và các điều kiện tiên quyết mà dự án của ứng dụng phải đáp ứng.
Lý do nên di chuyển sang Jetpack Media3
- Đây là nơi lưu trữ mới của ExoPlayer, trong khi
com.google.android.exoplayer2
đã ngừng hoạt động. - Truy cập Player API trên các thành phần/quy trình bằng
MediaBrowser
/MediaController
. - Sử dụng các chức năng mở rộng của API
MediaSession
vàMediaController
. - Quảng cáo các chức năng phát bằng quyền kiểm soát chi tiết đối với quyền truy cập.
- Đơn giản hoá ứng dụng bằng cách xoá
MediaSessionConnector
vàPlayerNotificationManager
. - Tương thích ngược với các API ứng dụng media-compat (
MediaBrowserCompat
/MediaControllerCompat
/MediaMetadataCompat
)
API Đa phương tiện cần di chuyển sang AndroidX Media3
- ExoPlayer và các tiện ích của ExoPlayer
Trong đó có tất cả các mô-đun của dự án ExoPlayer cũ, ngoại trừ mô-đun mediasession (đã ngừng hoạt động). Bạn có thể di chuyển các ứng dụng hoặc mô-đun tuỳ thuộc vào các gói trongcom.google.android.exoplayer2
bằng tập lệnh di chuyển. - MediaSessionConnector (tuỳ thuộc vào các gói
androidx.media.*
củaandroidx.media:media:1.4.3+
)
XoáMediaSessionConnector
và sử dụngandroidx.media3.session.MediaSession
để thay thế. - MediaBrowserServiceCompat (tuỳ thuộc vào các gói
androidx.media.*
củaandroidx.media:media:1.4.3+
)
Di chuyển các lớp con củaandroidx.media.MediaBrowserServiceCompat
sangandroidx.media3.session.MediaLibraryService
và mã bằngMediaBrowserCompat.MediaItem
sangandroidx.media3.common.MediaItem
. - MediaBrowserCompat (tuỳ thuộc vào các gói
android.support.v4.media.*
củaandroidx.media:media:1.4.3+
)
Di chuyển mã ứng dụng bằng cách sử dụngMediaBrowserCompat
hoặcMediaControllerCompat
để sử dụngandroidx.media3.session.MediaBrowser
vớiandroidx.media3.common.MediaItem
.
Điều kiện tiên quyết
Đảm bảo dự án của bạn đang được kiểm soát nguồn
Đảm bảo bạn có thể dễ dàng huỷ các thay đổi do công cụ di chuyển dựa trên tập lệnh áp dụng. Nếu dự án của bạn chưa được kiểm soát nguồn, thì bây giờ là thời điểm thích hợp để bắt đầu. Nếu vì lý do nào đó mà bạn không muốn làm như vậy, hãy tạo bản sao lưu dự án trước khi bắt đầu quá trình di chuyển.
Cập nhật ứng dụng
Bạn nên cập nhật dự án để sử dụng phiên bản mới nhất của thư viện ExoPlayer và xoá mọi lệnh gọi đến các phương thức không dùng nữa. Nếu dự định sử dụng tập lệnh để di chuyển, bạn cần phải khớp phiên bản mà bạn đang cập nhật với phiên bản do tập lệnh xử lý.
Tăng compileSdkVersion của ứng dụng lên ít nhất là 32.
Nâng cấp Gradle và trình bổ trợ Android Studio Gradle lên một phiên bản gần đây hoạt động với các phần phụ thuộc đã cập nhật ở trên. Ví dụ:
- Phiên bản trình bổ trợ Android cho Gradle: 7.1.0
- Phiên bản Gradle: 7.4
Thay thế tất cả câu lệnh nhập ký tự đại diện đang dùng dấu hoa thị (*) và dùng câu lệnh nhập đủ điều kiện: Xoá câu lệnh nhập ký tự đại diện và dùng Android Studio để nhập câu lệnh đủ điều kiện (F2 – Alt/Enter, F2 – Alt/Enter, ...).
Di chuyển từ
com.google.android.exoplayer2.PlayerView
sangcom.google.android.exoplayer2.StyledPlayerView
. Điều này là cần thiết vì không có thành phần nào tương đương vớicom.google.android.exoplayer2.PlayerView
trong AndroidX Media3.
Di chuyển ExoPlayer có hỗ trợ tập lệnh
Tập lệnh này giúp bạn chuyển từ com.google.android.exoplayer2
sang cấu trúc gói và mô-đun mới trong androidx.media3
. Tập lệnh này áp dụng một số quy trình kiểm tra xác thực cho dự án của bạn và in cảnh báo nếu quy trình xác thực không thành công.
Nếu không, nó sẽ áp dụng các mối liên kết của các lớp và gói được đổi tên trong tài nguyên của một dự án Android Gradle được viết bằng Java hoặc 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
Sử dụng tập lệnh di chuyển
Tải tập lệnh di chuyển xuống từ thẻ của dự án ExoPlayer trên GitHub tương ứng với phiên bản mà bạn đã cập nhật cho ứng dụng:
curl -o media3-migration.sh \ "https://raw.githubusercontent.com/google/ExoPlayer/r2.19.1/media3-migration.sh"
Làm cho tập lệnh có thể thực thi:
chmod 744 media3-migration.sh
Chạy tập lệnh bằng
--help
để tìm hiểu về các lựa chọn.Chạy tập lệnh bằng
-l
để liệt kê tập hợp các tệp được chọn để di chuyển (sử dụng-f
để buộc liệt kê mà không có cảnh báo):./media3-migration.sh -l -f /path/to/gradle/project/root
Chạy tập lệnh bằng
-m
để liên kết các gói, lớp và mô-đun với Media3. Khi chạy tập lệnh bằng tuỳ chọn-m
, các thay đổi sẽ được áp dụng cho các tệp đã chọn.- Dừng ở lỗi xác thực mà không thay đổi
./media3-migration.sh -m /path/to/gradle/project/root
- Thực thi bắt buộc
Nếu tập lệnh phát hiện thấy một lỗi vi phạm các điều kiện tiên quyết, bạn có thể buộc di chuyển bằng cờ
-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
Hoàn tất các bước thủ công này sau khi chạy tập lệnh bằng lựa chọn -m
:
- Kiểm tra cách tập lệnh thay đổi mã của bạn: Sử dụng một công cụ so sánh và khắc phục các vấn đề tiềm ẩn (cân nhắc báo cáo lỗi nếu bạn cho rằng tập lệnh có một vấn đề chung được đưa ra mà không truyền lựa chọn
-f
). - Tạo dự án: Sử dụng
./gradlew clean build
hoặc trong Android Studio, hãy chọn File > Sync Project with Gradle Files (Tệp > Đồng bộ hoá dự án với các tệp Gradle), sau đó chọn Build > Clean project (Xây dựng > Dọn dự án), rồi chọn Build > Rebuild project (Xây dựng > Tạo lại dự án) (giám sát quá trình tạo trong thẻ "Build – Build Output" (Xây dựng – Đầu ra của quá trình xây dựng) của Android Studio.
Các bước tiếp theo nên thực hiện:
- Giải quyết lựa chọn tham gia để nhận thông báo lỗi liên quan đến việc sử dụng các API không ổn định.
- Thay thế các lệnh gọi API không dùng nữa: Sử dụng API thay thế được đề xuất. Di chuyển con trỏ lên cảnh báo trong Android Studio và tham khảo JavaDoc của biểu tượng không dùng nữa để tìm hiểu xem nên sử dụng gì thay vì một lệnh gọi nhất định.
- Sắp xếp các câu lệnh nhập: Mở dự án trong Android Studio, sau đó nhấp chuột phải vào một nút thư mục gói trong trình xem dự án rồi chọn Optimize imports (Tối ưu hoá các câu lệnh nhập) trên các gói chứa tệp nguồn đã thay đổi.
Thay thế MediaSessionConnector
bằng androidx.media3.session.MediaSession
.
Trong thế giới MediaSessionCompat
cũ, MediaSessionConnector
chịu trách nhiệm đồng bộ hoá trạng thái của trình phát với trạng thái của phiên và nhận các lệnh từ bộ điều khiển cần uỷ quyền cho các phương thức trình phát thích hợp. Với AndroidX Media3, việc này được thực hiện trực tiếp bằng MediaSession
mà không cần đến trình kết nối.
Xoá tất cả các tham chiếu và việc sử dụng MediaSessionConnector: Nếu bạn đã sử dụng tập lệnh tự động để di chuyển các lớp và gói ExoPlayer, thì tập lệnh có thể đã khiến mã của bạn không thể biên dịch được liên quan đến
MediaSessionConnector
không thể phân giải. Android Studio sẽ cho bạn thấy mã bị hỏng khi bạn cố gắng tạo hoặc khởi động ứng dụng.Trong tệp
build.gradle
nơi bạn duy trì các phần phụ thuộc, hãy thêm một phần phụ thuộc triển khai vào mô-đun phiên AndroidX Media3 và xoá phần phụ thuộc cũ:implementation "androidx.media3:media3-session:1.7.1"
Thay thế
MediaSessionCompat
bằngandroidx.media3.session.MediaSession
.Tại vị trí mã mà bạn đã tạo
MediaSessionCompat
cũ, hãy dùngandroidx.media3.session.MediaSession.Builder
để tạoMediaSession
. Truyền trình phát để tạo trình tạo phiên.val player = ExoPlayer.Builder(context).build() mediaSession = MediaSession.Builder(context, player) .setSessionCallback(MySessionCallback()) .build()
Triển khai
MySessionCallback
theo yêu cầu của ứng dụng. Đây là bước không bắt buộc. Nếu bạn muốn cho phép bộ điều khiển thêm các mục nội dung nghe nhìn vào trình phát, hãy triển khaiMediaSession.Callback.onAddMediaItems()
. Thư viện này cung cấp nhiều phương thức API hiện tại và cũ để thêm các mục nội dung nghe nhìn vào trình phát để phát theo cách tương thích ngược. Trong đó có các phương thứcMediaController.set/addMediaItems()
của bộ điều khiển Media3, cũng như các phương thứcTransportControls.prepareFrom*/playFrom*
của API cũ. Bạn có thể xem một ví dụ về hoạt động triển khaionAddMediaItems
trongPlaybackService
của ứng dụng minh hoạ phiên.Phát hành phiên đa phương tiện tại vị trí mã nơi bạn đã huỷ phiên trước khi di chuyển:
mediaSession?.run { player.release() release() mediaSession = null }
Chức năng MediaSessionConnector
trong Media3
Bảng sau đây cho thấy các API Media3 xử lý chức năng được triển khai trước đây trong MediaSessionConnector
.
MediaSessionConnector | AndroidX Media3 |
---|---|
CustomActionProvider |
MediaSession.Callback.onCustomCommand()/
MediaSession.setMediaButtonPreferences() |
PlaybackPreparer |
MediaSession.Callback.onAddMediaItems()
(prepare() được gọi nội bộ)
|
QueueNavigator |
ForwardingSimpleBasePlayer |
QueueEditor |
MediaSession.Callback.onAddMediaItems() |
RatingCallback |
MediaSession.Callback.onSetRating() |
PlayerNotificationManager |
DefaultMediaNotificationProvider/
MediaNotification.Provider |
Di chuyển MediaBrowserService
sang MediaLibraryService
AndroidX Media3 giới thiệu MediaLibraryService
để thay thế MediaBrowserServiceCompat
. JavaDoc của MediaLibraryService
và siêu lớp MediaSessionService
cung cấp thông tin giới thiệu hữu ích về API và mô hình lập trình không đồng bộ của dịch vụ.
MediaLibraryService
có khả năng tương thích ngược với MediaBrowserService
. Một ứng dụng khách đang dùng MediaBrowserCompat
hoặc MediaControllerCompat
, tiếp tục hoạt động mà không cần thay đổi mã khi kết nối với MediaLibraryService
. Đối với một ứng dụng khách, việc ứng dụng của bạn đang sử dụng MediaLibraryService
hay MediaBrowserServiceCompat
cũ là điều hiển nhiên.

Để khả năng tương thích ngược hoạt động, bạn cần đăng ký cả hai giao diện dịch vụ với dịch vụ của mình trong
AndroidManifest.xml
. Bằng cách này, một ứng dụng sẽ tìm thấy dịch vụ của bạn theo giao diện dịch vụ bắt buộc:<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>
Trong tệp
build.gradle
nơi bạn duy trì các phần phụ thuộc, hãy thêm một phần phụ thuộc triển khai vào mô-đun phiên AndroidX Media3 và xoá phần phụ thuộc cũ:implementation "androidx.media3:media3-session:1.7.1"
Thay đổi dịch vụ của bạn để kế thừa từ
MediaLibraryService
thay vìMediaBrowserService
Như đã nói trước đó,MediaLibraryService
tương thích vớiMediaBrowserService
cũ. Theo đó, API rộng hơn mà dịch vụ này cung cấp cho các ứng dụng vẫn không thay đổi. Do đó, có khả năng một ứng dụng có thể giữ lại hầu hết logic cần thiết để triển khaiMediaBrowserService
và điều chỉnh logic đó choMediaLibraryService
mới.Sau đây là những điểm khác biệt chính so với
MediaBrowserServiceCompat
cũ:Triển khai các phương thức trong vòng đời của dịch vụ: Các phương thức cần được ghi đè trên chính dịch vụ là
onCreate/onDestroy
, trong đó ứng dụng phân bổ/phát hành phiên thư viện, trình phát và các tài nguyên khác. Ngoài các phương thức vòng đời dịch vụ tiêu chuẩn, ứng dụng cần ghi đèonGetSession(MediaSession.ControllerInfo)
để trả vềMediaLibrarySession
được tạo trongonCreate
.Triển khai MediaLibraryService.MediaLibrarySessionCallback: Để tạo một phiên, bạn cần có một
MediaLibraryService.MediaLibrarySessionCallback
triển khai các phương thức API miền thực tế. Vì vậy, thay vì ghi đè các phương thức API của dịch vụ cũ, bạn sẽ ghi đè các phương thức củaMediaLibrarySession.Callback
.Sau đó, lệnh gọi lại được dùng để tạo
MediaLibrarySession
:mediaLibrarySession = MediaLibrarySession.Builder(this, player, MySessionCallback()) .build()
Tìm toàn bộ API của MediaLibrarySessionCallback trong tài liệu API.
Triển khai
MediaSession.Callback.onAddMediaItems()
: Lệnh gọi lạionAddMediaItems(MediaSession, ControllerInfo, List<MediaItem>)
phục vụ nhiều phương thức API hiện tại và cũ để thêm các mục nội dung nghe nhìn vào trình phát để phát theo cách tương thích ngược. Trong đó có các phương thứcMediaController.set/addMediaItems()
của bộ điều khiển Media3, cũng như các phương thứcTransportControls.prepareFrom*/playFrom*
của API cũ. Bạn có thể xem một ví dụ về cách triển khai lệnh gọi lại trongPlaybackService
của ứng dụng minh hoạ phiên.AndroidX Media3 đang sử dụng
androidx.media3.common.MediaItem
thay vì MediaBrowserCompat.MediaItem và MediaMetadataCompat. Bạn cần thay đổi các phần mã được liên kết với các lớp cũ cho phù hợp hoặc ánh xạ đếnMediaItem
của Media3.Mô hình lập trình không đồng bộ chung đã thay đổi thành
Futures
, trái ngược với phương phápResult
có thể tách rời củaMediaBrowserServiceCompat
. Quá trình triển khai dịch vụ của bạn có thể trả về mộtListenableFuture
không đồng bộ thay vì tách kết quả hoặc trả về một Future ngay lập tức để trực tiếp trả về một giá trị.
Xoá PlayerNotificationManager
MediaLibraryService
tự động hỗ trợ thông báo về nội dung nghe nhìn và bạn có thể xoá PlayerNotificationManager
khi dùng MediaLibraryService
hoặc MediaSessionService
.
Một ứng dụng có thể tuỳ chỉnh thông báo bằng cách đặt một MediaNotification.Provider
tuỳ chỉnh trong onCreate()
thay thế DefaultMediaNotificationProvider
. Sau đó, MediaLibraryService
sẽ đảm nhận việc bắt đầu dịch vụ ở nền trước khi cần.
Bằng cách ghi đè MediaLibraryService.updateNotification()
, ứng dụng có thể tiếp tục hoàn toàn quyền sở hữu việc đăng thông báo và bắt đầu/dừng dịch vụ ở nền trước khi cần.
Di chuyển mã ứng dụng bằng MediaBrowser
Với AndroidX Media3, MediaBrowser
triển khai các giao diện MediaController/Player
và có thể dùng để kiểm soát quá trình phát nội dung nghe nhìn ngoài việc duyệt qua thư viện nội dung nghe nhìn. Nếu phải tạo MediaBrowserCompat
và MediaControllerCompat
trong thế giới cũ, bạn có thể làm điều tương tự bằng cách chỉ sử dụng MediaBrowser
trong Media3.
Bạn có thể tạo một MediaBrowser
và chờ kết nối được thiết lập với dịch vụ:
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)
}
Hãy xem phần Kiểm soát hoạt động phát trong phiên nội dung nghe nhìn để tìm hiểu cách tạo một MediaController
để kiểm soát hoạt động phát ở chế độ nền.
Các bước tiếp theo và dọn dẹp
Lỗi API không ổn định
Sau khi di chuyển sang Media3, bạn có thể thấy các lỗi lint về việc sử dụng API không ổn định.
Bạn có thể sử dụng các API này một cách an toàn và lỗi lint là sản phẩm phụ của các đảm bảo khả năng tương thích nhị phân mới của chúng tôi. Nếu không yêu cầu khả năng tương thích nhị phân nghiêm ngặt, bạn có thể chặn các lỗi này một cách an toàn bằng chú thích @OptIn
.
Thông tin khái quát
Cả ExoPlayer phiên bản 1 và 2 đều không đảm bảo chắc chắn về khả năng tương thích nhị phân của thư viện giữa các phiên bản tiếp theo. Theo thiết kế, bề mặt API ExoPlayer rất lớn để cho phép các ứng dụng tuỳ chỉnh hầu hết mọi khía cạnh của quá trình phát. Các phiên bản tiếp theo của ExoPlayer đôi khi sẽ đổi tên biểu tượng hoặc có những thay đổi khác gây ảnh hưởng (ví dụ: các phương thức bắt buộc mới trên giao diện). Trong hầu hết các trường hợp, những thay đổi này đã được giảm thiểu bằng cách giới thiệu biểu tượng mới cùng với việc ngừng sử dụng biểu tượng cũ trong một vài phiên bản, để cho phép nhà phát triển có thời gian di chuyển các cách sử dụng của họ, nhưng điều này không phải lúc nào cũng có thể.
Những thay đổi mang tính đột phá này đã gây ra 2 vấn đề cho người dùng thư viện ExoPlayer phiên bản 1 và phiên bản 2:
- Việc nâng cấp từ lên phiên bản ExoPlayer có thể khiến mã ngừng biên dịch.
- Một ứng dụng phụ thuộc vào ExoPlayer cả trực tiếp và thông qua một thư viện trung gian phải đảm bảo rằng cả hai phần phụ thuộc đều là cùng một phiên bản, nếu không, sự không tương thích nhị phân có thể dẫn đến sự cố trong thời gian chạy.
Những điểm cải tiến trong Media3
Media3 đảm bảo khả năng tương thích nhị phân cho một nhóm nhỏ nền tảng API. Những phần không đảm bảo khả năng tương thích của tệp nhị phân được đánh dấu bằng @UnstableApi
. Để làm rõ sự khác biệt này, việc sử dụng các biểu tượng API không ổn định sẽ tạo ra lỗi lint, trừ phi chúng được chú thích bằng @OptIn
.
Sau khi di chuyển từ ExoPlayer phiên bản 2 sang Media3, bạn có thể thấy nhiều lỗi lint API không ổn định. Điều này có thể khiến Media3 có vẻ "kém ổn định" hơn ExoPlayer phiên bản 2. Điều này không đúng. Các phần "không ổn định" của API Media3 có cùng mức độ ổn định như toàn bộ khu vực API ExoPlayer phiên bản 2 và các đảm bảo về khu vực API Media3 ổn định hoàn toàn không có trong ExoPlayer phiên bản 2. Điểm khác biệt đơn giản là giờ đây, lỗi lint sẽ cảnh báo cho bạn về các mức độ ổn định khác nhau.
Xử lý các lỗi lint API không ổn định
Hãy xem phần khắc phục sự cố về các lỗi tìm lỗi mã nguồn này để biết thông tin chi tiết về cách chú thích các lượt sử dụng Java và Kotlin của API không ổn định bằng @OptIn
.
API không dùng nữa
Bạn có thể nhận thấy rằng các lệnh gọi đến API không được dùng nữa sẽ bị gạch ngang trong Android Studio. Bạn nên thay thế những lệnh gọi như vậy bằng phương thức thay thế phù hợp. Di chuột lên biểu tượng để xem JavaDoc cho biết API nào cần sử dụng thay thế.

Mã mẫu và ứng dụng minh hoạ
- Ứng dụng minh hoạ phiên AndroidX Media3 (thiết bị di động và WearOS)
- Thao tác tuỳ chỉnh
- Thông báo giao diện người dùng hệ thống, MediaButton/BT
- Chế độ điều khiển phát của Trợ lý Google
- UAMP: Trình phát nội dung nghe nhìn trên Android (nhánh media3) (thiết bị di động, AutomotiveOS)
- Thông báo giao diện người dùng hệ thống, MediaButton/BT, Tiếp tục phát
- Chế độ điều khiển phát của Trợ lý Google/WearOS
- AutomotiveOS: lệnh tuỳ chỉnh và đăng nhập