Khắc phục sự cố


Khắc phục lỗi "Không được phép sử dụng lưu lượng truy cập HTTP ở dạng văn bản thuần tuý"

Lỗi này sẽ xảy ra nếu ứng dụng của bạn yêu cầu lưu lượng truy cập HTTP ở dạng văn bản thô (tức là http:// thay vì https://) khi Cấu hình bảo mật mạng của ứng dụng không cho phép lưu lượng truy cập này. Nếu ứng dụng của bạn nhắm đến Android 9 (API cấp 28) trở lên, thì lưu lượng truy cập HTTP cleartext sẽ bị vô hiệu hoá theo cấu hình mặc định.

Nếu ứng dụng của bạn cần hoạt động với lưu lượng truy cập HTTP qua văn bản thô, thì bạn cần sử dụng một Cấu hình bảo mật mạng cho phép lưu lượng truy cập đó. Hãy xem tài liệu về bảo mật mạng của Android để biết thông tin chi tiết. Để bật tất cả lưu lượng truy cập HTTP văn bản thô, bạn chỉ cần thêm android:usesCleartextTraffic="true" vào phần tử application của AndroidManifest.xml trong ứng dụng.

Ứng dụng minh hoạ ExoPlayer sử dụng Cấu hình bảo mật mạng mặc định, do đó, ứng dụng này không cho phép lưu lượng truy cập HTTP qua văn bản thô. Bạn có thể bật tính năng này theo hướng dẫn ở trên.

Khắc phục lỗi "SSLHandshakeException", "CertPathValidatorException" và "ERR_CERT_AUTHORITY_INVALID"

SSLHandshakeException, CertPathValidatorExceptionERR_CERT_AUTHORITY_INVALID đều cho biết có vấn đề với chứng chỉ SSL của máy chủ. Những lỗi này không dành riêng cho ExoPlayer. Hãy xem tài liệu về SSL của Android để biết thêm thông tin chi tiết.

Tại sao một số tệp đa phương tiện không tua được?

Theo mặc định, ExoPlayer không hỗ trợ tìm kiếm trong nội dung nghe nhìn mà phương thức duy nhất để thực hiện các thao tác tìm kiếm chính xác là để trình phát quét và lập chỉ mục toàn bộ tệp. ExoPlayer coi những tệp như vậy là không thể tìm kiếm. Hầu hết các định dạng vùng chứa nội dung nghe nhìn hiện đại đều có siêu dữ liệu để tìm kiếm (chẳng hạn như chỉ mục mẫu), có thuật toán tìm kiếm được xác định rõ (ví dụ: tìm kiếm phân đôi nội suy cho Ogg) hoặc cho biết nội dung của chúng có tốc độ bit không đổi. ExoPlayer có thể thực hiện các thao tác tìm kiếm hiệu quả và được hỗ trợ trong những trường hợp này.

Nếu bạn cần tìm kiếm nhưng có nội dung nghe nhìn không tìm kiếm được, thì bạn nên chuyển đổi nội dung của mình để sử dụng một định dạng vùng chứa phù hợp hơn. Đối với các tệp MP3, ADTS và AMR, bạn cũng có thể bật tính năng tìm kiếm với giả định rằng các tệp có tốc độ bit không đổi, như mô tả tại đây.

Tại sao tính năng tìm kiếm lại không chính xác trong một số tệp MP3?

Về cơ bản, các tệp MP3 có tốc độ bit thay đổi (VBR) không phù hợp với những trường hợp sử dụng đòi hỏi khả năng tìm kiếm chính xác. Có 2 lý do dẫn đến điều này:

  1. Để tua chính xác, tốt nhất là định dạng vùng chứa sẽ cung cấp một bản đồ chính xác từ thời gian đến byte trong tiêu đề. Quy trình liên kết này cho phép người chơi liên kết thời gian tìm kiếm đã yêu cầu với độ lệch byte tương ứng, đồng thời bắt đầu yêu cầu, phân tích cú pháp và phát nội dung nghe nhìn từ độ lệch đó. Thật không may, các tiêu đề có sẵn để chỉ định mối liên kết này trong MP3 (chẳng hạn như tiêu đề XING) thường không chính xác.
  2. Đối với các định dạng vùng chứa không cung cấp thông tin ánh xạ chính xác từ thời gian đến byte (hoặc không cung cấp thông tin ánh xạ từ thời gian đến byte), bạn vẫn có thể thực hiện thao tác tìm kiếm chính xác nếu vùng chứa có dấu thời gian mẫu tuyệt đối trong luồng. Trong trường hợp này, người chơi có thể ánh xạ thời gian tìm kiếm đến một phỏng đoán tốt nhất về độ lệch byte tương ứng, bắt đầu yêu cầu nội dung nghe nhìn từ độ lệch đó, phân tích cú pháp dấu thời gian mẫu tuyệt đối đầu tiên và thực hiện hiệu quả một tìm kiếm nhị phân có hướng dẫn vào nội dung nghe nhìn cho đến khi tìm thấy mẫu phù hợp. Rất tiếc, MP3 không có dấu thời gian mẫu tuyệt đối trong luồng, nên không thể sử dụng phương pháp này.

Vì những lý do này, cách duy nhất để thực hiện thao tác tìm kiếm chính xác trong tệp MP3 có tốc độ bit thay đổi là quét toàn bộ tệp và tự tạo mối liên kết giữa thời gian và byte trong trình phát. Bạn có thể bật chiến lược này bằng cách sử dụng FLAG_ENABLE_INDEX_SEEKING. Bạn có thể đặt chiến lược này trên DefaultExtractorsFactory bằng cách sử dụng setMp3ExtractorFlags. Xin lưu ý rằng phương pháp này không phù hợp với các tệp MP3 lớn, đặc biệt là nếu người dùng cố gắng tìm đến gần cuối luồng ngay sau khi bắt đầu phát. Điều này đòi hỏi trình phát phải đợi cho đến khi tải xuống và lập chỉ mục toàn bộ luồng trước khi thực hiện thao tác tìm kiếm. Trong ExoPlayer, chúng tôi quyết định tối ưu hoá tốc độ thay vì độ chính xác trong trường hợp này và do đó, FLAG_ENABLE_INDEX_SEEKING sẽ bị tắt theo mặc định.

Nếu kiểm soát nội dung nghe nhìn mà bạn đang phát, bạn nên sử dụng một định dạng vùng chứa phù hợp hơn, chẳng hạn như MP4. Chúng tôi không biết có trường hợp sử dụng nào mà MP3 là lựa chọn tốt nhất cho định dạng nội dung nghe nhìn.

Tại sao video của tôi tua đến một đoạn khác rất chậm?

Khi chuyển đến một vị trí phát mới trong video, trình phát cần thực hiện 2 việc:

  1. Tải dữ liệu tương ứng với vị trí phát mới vào vùng đệm (bước này có thể không cần thiết nếu dữ liệu này đã được lưu vào vùng đệm).
  2. Xoá bộ giải mã video và bắt đầu giải mã từ khung hình I (khung hình chính) trước vị trí phát mới, do phương pháp mã hoá trong khung hình mà hầu hết các định dạng nén video đều sử dụng. Để đảm bảo thao tác tìm kiếm diễn ra chính xác (tức là quá trình phát bắt đầu chính xác tại vị trí tìm kiếm), tất cả các khung hình giữa khung hình I trước đó và vị trí tìm kiếm cần được giải mã và loại bỏ ngay lập tức (mà không hiển thị trên màn hình).

Độ trễ do (1) gây ra có thể được giảm thiểu bằng cách tăng lượng dữ liệu được lưu vào bộ nhớ đệm trong bộ nhớ của trình phát hoặc lưu trước dữ liệu vào ổ đĩa.

Bạn có thể giảm độ trễ do (2) gây ra bằng cách giảm độ chính xác của thao tác tìm kiếm bằng cách sử dụng ExoPlayer.setSeekParameters hoặc mã hoá lại video để có nhiều khung hình I hơn (điều này sẽ dẫn đến tệp đầu ra lớn hơn).

Tại sao một số tệp MPEG-TS không phát được?

Một số tệp MPEG-TS không chứa dấu phân cách đơn vị truy cập (AUD). Theo mặc định, ExoPlayer dựa vào AUD để phát hiện ranh giới khung hình một cách hiệu quả. Tương tự, một số tệp MPEG-TS không chứa khung hình khoá IDR. Theo mặc định, đây là loại khung hình chính duy nhất mà ExoPlayer xem xét.

ExoPlayer sẽ có vẻ như bị kẹt ở trạng thái đệm khi được yêu cầu phát một tệp MPEG-TS thiếu AUD hoặc khung hình khoá IDR. Nếu cần phát các tệp như vậy, bạn có thể phát bằng cách sử dụng lần lượt FLAG_DETECT_ACCESS_UNITSFLAG_ALLOW_NON_IDR_KEYFRAMES. Bạn có thể đặt các cờ này trên DefaultExtractorsFactory bằng cách sử dụng setTsExtractorFlags hoặc trên DefaultHlsExtractorFactory bằng hàm khởi tạo. Việc sử dụng FLAG_DETECT_ACCESS_UNITS không có tác dụng phụ nào khác ngoài việc tốn nhiều tài nguyên tính toán so với tính năng phát hiện ranh giới khung hình dựa trên AUD. Việc sử dụng FLAG_ALLOW_NON_IDR_KEYFRAMES có thể dẫn đến lỗi hình ảnh tạm thời khi bắt đầu phát và ngay sau khi tìm kiếm khi phát một số tệp MPEG-TS.

Tại sao không tìm thấy phụ đề trong một số tệp MPEG-TS?

Một số tệp MPEG-TS có chứa các bản phụ đề CEA-608 nhưng không khai báo các bản phụ đề này trong siêu dữ liệu vùng chứa, nên ExoPlayer không thể phát hiện các bản phụ đề đó. Bạn có thể chỉ định mọi bản phụ đề theo cách thủ công bằng cách cung cấp danh sách các định dạng phụ đề dự kiến cho DefaultExtractorsFactory, bao gồm cả các kênh hỗ trợ tiếp cận có thể dùng để xác định các bản phụ đề đó trong luồng MPEG-TS:

Kotlin

val extractorsFactory =
  DefaultExtractorsFactory()
    .setTsSubtitleFormats(
      listOf(
        Format.Builder()
          .setSampleMimeType(MimeTypes.APPLICATION_CEA608)
          .setAccessibilityChannel(accessibilityChannel)
          // Set other subtitle format info, such as language.
          .build()
      )
    )
val player: Player =
  ExoPlayer.Builder(context, DefaultMediaSourceFactory(context, extractorsFactory)).build()

Java

DefaultExtractorsFactory extractorsFactory =
    new DefaultExtractorsFactory()
        .setTsSubtitleFormats(
            ImmutableList.of(
                new Format.Builder()
                    .setSampleMimeType(MimeTypes.APPLICATION_CEA608)
                    .setAccessibilityChannel(accessibilityChannel)
                    // Set other subtitle format info, such as language.
                    .build()));
Player player =
    new ExoPlayer.Builder(context, new DefaultMediaSourceFactory(context, extractorsFactory))
        .build();

Tại sao một số tệp MP4/FMP4 lại phát không chính xác?

Một số tệp MP4/FMP4 chứa danh sách chỉnh sửa giúp viết lại dòng thời gian của nội dung nghe nhìn bằng cách bỏ qua, di chuyển hoặc lặp lại danh sách mẫu. ExoPlayer hỗ trợ một phần việc áp dụng danh sách chỉnh sửa. Ví dụ: nó có thể trì hoãn hoặc lặp lại các nhóm mẫu bắt đầu trên một mẫu đồng bộ hoá, nhưng không cắt bớt các mẫu âm thanh hoặc phương tiện quảng cáo trước video cho những nội dung chỉnh sửa không bắt đầu trên một mẫu đồng bộ hoá.

Nếu bạn thấy một phần nội dung nghe nhìn bị thiếu hoặc lặp lại một cách bất ngờ, hãy thử đặt Mp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS hoặc FragmentedMp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS. Thao tác này sẽ khiến trình trích xuất hoàn toàn bỏ qua danh sách chỉnh sửa. Bạn có thể đặt các giá trị này trên DefaultExtractorsFactory bằng cách sử dụng setMp4ExtractorFlags hoặc setFragmentedMp4ExtractorFlags.

Tại sao một số luồng phát không thành công với mã phản hồi HTTP 301 hoặc 302?

Mã phản hồi HTTP 301 và 302 đều cho biết lệnh chuyển hướng. Bạn có thể xem nội dung mô tả ngắn gọn trên Wikipedia. Khi đưa ra yêu cầu và nhận được phản hồi có mã trạng thái 301 hoặc 302, ExoPlayer thường sẽ chuyển hướng và bắt đầu phát như bình thường. Trường hợp duy nhất mà điều này không xảy ra theo mặc định là đối với lệnh chuyển hướng giữa các giao thức. Lệnh chuyển hướng trên nhiều giao thức là lệnh chuyển hướng từ HTTPS sang HTTP hoặc ngược lại (hoặc ít phổ biến hơn, giữa một cặp giao thức khác). Bạn có thể kiểm tra xem một URL có gây ra lệnh chuyển hướng liên giao thức hay không bằng cách sử dụng công cụ dòng lệnh wget như sau:

wget "https://yourserver.example.com/test.mp3" 2>&1  | grep Location

Kết quả đầu ra sẽ có dạng như sau:

Location: https://secondserver.example.net/test.mp3 [following]
Location: http://thirdserver.example.org/test.mp3 [following]

Trong ví dụ này, có 2 lệnh chuyển hướng. Lệnh chuyển hướng đầu tiên là từ https://yourserver.example.com/test.mp3 đến https://secondserver.example.net/test.mp3. Cả hai đều là HTTPS, vì vậy đây không phải là lệnh chuyển hướng liên giao thức. Lệnh chuyển hướng thứ hai là từ https://secondserver.example.net/test.mp3 đến http://thirdserver.example.org/test.mp3. Lệnh này chuyển hướng từ HTTPS sang HTTP, do đó là lệnh chuyển hướng trên nhiều giao thức. ExoPlayer sẽ không tuân theo lệnh chuyển hướng này trong cấu hình mặc định, nghĩa là quá trình phát sẽ không thành công.

Nếu cần, bạn có thể định cấu hình ExoPlayer để tuân theo các lệnh chuyển hướng trên nhiều giao thức khi tạo thực thể DefaultHttpDataSource.Factory được dùng trong ứng dụng. Tìm hiểu về cách chọn và định cấu hình ngăn xếp mạng tại đây.

Tại sao một số luồng gặp lỗi UnrecognizedInputFormatException?

Câu hỏi này liên quan đến lỗi phát ở dạng sau:

UnrecognizedInputFormatException: None of the available extractors
(MatroskaExtractor, FragmentedMp4Extractor, ...) could read the stream.

Có 2 nguyên nhân có thể gây ra lỗi này. Nguyên nhân phổ biến nhất là bạn đang cố gắng phát nội dung DASH (mpd), HLS (m3u8) hoặc SmoothStreaming (ism, isml), nhưng trình phát lại cố gắng phát nội dung đó dưới dạng luồng phát trực tuyến tăng dần. Để phát các luồng như vậy, bạn phải phụ thuộc vào mô-đun ExoPlayer tương ứng. Trong trường hợp URI luồng không kết thúc bằng đuôi tệp tiêu chuẩn, bạn cũng có thể truyền MimeTypes.APPLICATION_MPD, MimeTypes.APPLICATION_M3U8 hoặc MimeTypes.APPLICATION_SS đến setMimeType của MediaItem.Builder để chỉ định rõ loại luồng.

Nguyên nhân thứ hai (ít phổ biến hơn) là do ExoPlayer không hỗ trợ định dạng vùng chứa của nội dung nghe nhìn mà bạn đang cố gắng phát. Trong trường hợp này, lỗi xảy ra như dự kiến. Tuy nhiên, bạn có thể gửi yêu cầu về tính năng cho trình theo dõi lỗi của chúng tôi, bao gồm cả thông tin chi tiết về định dạng vùng chứa và một luồng kiểm thử. Vui lòng tìm kiếm yêu cầu về tính năng hiện có trước khi gửi yêu cầu mới.

Vì sao setPlaybackParameters không hoạt động đúng cách trên một số thiết bị?

Khi chạy bản gỡ lỗi của ứng dụng trên Android M trở xuống, bạn có thể gặp phải hiệu suất không ổn định, các cấu phần phần mềm có thể nghe được và mức sử dụng CPU cao khi dùng API setPlaybackParameters. Điều này là do một hoạt động tối ưu hoá quan trọng đối với API này bị vô hiệu hoá đối với các bản gỡ lỗi chạy trên những phiên bản Android này.

Điều quan trọng cần lưu ý là vấn đề này chỉ ảnh hưởng đến các bản gỡ lỗi. Việc này không ảnh hưởng đến các bản phát hành, vì tính năng tối ưu hoá luôn được bật. Do đó, các bản phát hành mà bạn cung cấp cho người dùng cuối sẽ không bị ảnh hưởng bởi vấn đề này.

Lỗi "Player is accessed on the wrong thread" (Truy cập vào trình phát trên luồng không chính xác) có nghĩa là gì?

Xem Lưu ý về việc tạo luồng trên trang bắt đầu.

Làm cách nào để khắc phục lỗi "Unexpected status line: ICY 200 OK" (Dòng trạng thái không mong muốn: ICY 200 OK)?

Vấn đề này có thể xảy ra nếu phản hồi của máy chủ bao gồm một dòng trạng thái ICY, thay vì dòng trạng thái tuân thủ HTTP. Các dòng trạng thái ICY không được dùng nữa và bạn không nên sử dụng. Vì vậy, nếu kiểm soát máy chủ, bạn nên cập nhật máy chủ để cung cấp một phản hồi tuân thủ HTTP. Nếu không thể thực hiện việc này, thì việc sử dụng thư viện ExoPlayer OkHttp sẽ giải quyết vấn đề, vì thư viện này có thể xử lý chính xác các dòng trạng thái ICY.

Làm cách nào để truy vấn xem luồng đang phát có phải là luồng phát trực tiếp hay không?

Bạn có thể truy vấn phương thức isCurrentWindowLive của trình phát. Ngoài ra, bạn có thể kiểm tra isCurrentWindowDynamic để biết liệu cửa sổ có linh hoạt hay không (tức là vẫn cập nhật theo thời gian).

Làm cách nào để tiếp tục phát âm thanh khi ứng dụng của tôi chạy trong nền?

Hãy làm theo các bước sau để đảm bảo âm thanh tiếp tục phát khi ứng dụng của bạn ở chế độ nền:

  1. Bạn cần có một dịch vụ trên nền trước đang chạy. Điều này ngăn hệ thống tắt quy trình của bạn để giải phóng tài nguyên.
  2. Bạn cần có WifiLockWakeLock. Những chế độ này đảm bảo rằng hệ thống duy trì trạng thái hoạt động của CPU và đài Wi-Fi. Bạn có thể dễ dàng thực hiện việc này nếu sử dụng ExoPlayer bằng cách gọi setWakeMode. Thao tác này sẽ tự động lấy và giải phóng các khoá cần thiết vào đúng thời điểm.

Bạn cần giải phóng các khoá (nếu không sử dụng setWakeMode) và dừng dịch vụ ngay khi không còn phát âm thanh.

Tại sao ExoPlayer hỗ trợ nội dung của tôi nhưng thư viện ExoPlayer Cast thì không?

Có thể nội dung mà bạn đang cố gắng phát không được bật CORS. Khung truyền yêu cầu nội dung phải được bật CORS để phát.

Tại sao nội dung không phát được nhưng không có lỗi nào xuất hiện?

Có thể thiết bị mà bạn đang phát nội dung không hỗ trợ một định dạng mẫu nội dung nghe nhìn cụ thể. Bạn có thể dễ dàng xác nhận điều này bằng cách thêm một EventLogger làm trình nghe vào trình phát và tìm một dòng tương tự như dòng này trong Logcat:

[ ] Track:x, id=x, mimeType=mime/type, ... , supported=NO_UNSUPPORTED_TYPE

NO_UNSUPPORTED_TYPE có nghĩa là thiết bị không thể giải mã định dạng mẫu nội dung nghe nhìn do mimeType chỉ định. Hãy xem tài liệu về định dạng nội dung nghe nhìn trên Android để biết thông tin về các định dạng mẫu được hỗ trợ. Làm cách nào để lấy một thư viện giải mã để tải và dùng cho quá trình phát? cũng có thể hữu ích.

Làm cách nào để lấy một thư viện giải mã để tải và sử dụng cho quá trình phát?

  • Hầu hết các thư viện trình giải mã đều có các bước thủ công để kiểm tra và tạo phần phụ thuộc, vì vậy, hãy nhớ làm theo các bước trong tệp README cho thư viện có liên quan. Ví dụ: đối với thư viện ExoPlayer FFmpeg, bạn cần làm theo hướng dẫn trong libraries/decoder_ffmpeg/README.md, bao gồm cả việc truyền cờ cấu hình để bật bộ giải mã cho mọi định dạng bạn muốn phát.
  • Đối với các thư viện có mã gốc, hãy đảm bảo rằng bạn đang sử dụng đúng phiên bản Android NDK như được chỉ định trong tệp README và chú ý đến mọi lỗi xuất hiện trong quá trình định cấu hình và xây dựng. Bạn sẽ thấy các tệp .so xuất hiện trong thư mục con libs của đường dẫn thư viện cho từng cấu trúc được hỗ trợ sau khi làm theo các bước trong tệp README.
  • Để dùng thử tính năng phát bằng thư viện trong ứng dụng minh hoạ, hãy xem phần bật bộ giải mã đi kèm. Hãy xem tệp README của thư viện để biết hướng dẫn về cách sử dụng thư viện trong ứng dụng của riêng bạn.
  • Nếu đang dùng DefaultRenderersFactory, bạn sẽ thấy một dòng nhật ký cấp thông tin như "Loaded FfmpegAudioRenderer" (Đã tải FfmpegAudioRenderer) trong Logcat khi bộ giải mã tải. Nếu thiếu phần này, hãy đảm bảo ứng dụng có một phần phụ thuộc vào thư viện giải mã.
  • Nếu bạn thấy nhật ký ở cấp cảnh báo từ LibraryLoader trong Logcat, điều này cho biết quá trình tải thành phần gốc của thư viện không thành công. Nếu điều này xảy ra, hãy kiểm tra để đảm bảo bạn đã làm theo các bước trong tệp README của thư viện một cách chính xác và không có lỗi nào xuất hiện trong khi làm theo hướng dẫn.

Nếu bạn vẫn gặp vấn đề khi sử dụng các thư viện giải mã, vui lòng kiểm tra trình theo dõi vấn đề của Media3 để xem có vấn đề nào liên quan gần đây hay không. Nếu bạn cần báo cáo một vấn đề mới và vấn đề đó liên quan đến việc tạo phần gốc của thư viện, vui lòng cung cấp toàn bộ đầu ra dòng lệnh khi chạy hướng dẫn README để giúp chúng tôi chẩn đoán vấn đề.

Tôi có thể phát video trên YouTube trực tiếp bằng ExoPlayer không?

Không, ExoPlayer không thể phát video trên YouTube, chẳng hạn như URL có dạng https://www.youtube.com/watch?v=.... Thay vào đó, bạn nên sử dụng YouTube IFrame Player API. Đây là cách chính thức để phát video trên YouTube trên Android.

Video phát bị giật

Thiết bị có thể không giải mã được nội dung đủ nhanh nếu, ví dụ: tốc độ bit hoặc độ phân giải của nội dung vượt quá khả năng của thiết bị. Bạn có thể cần sử dụng nội dung có chất lượng thấp hơn để đạt được hiệu suất tốt trên những thiết bị như vậy.

Nếu gặp phải tình trạng video bị giật trên thiết bị chạy phiên bản Android từ Android 6.0 (API cấp 23) đến Android 11 (API cấp 30), đặc biệt là khi phát nội dung được bảo vệ bằng DRM hoặc nội dung có tốc độ khung hình cao, bạn có thể thử bật tính năng xếp hàng bộ đệm không đồng bộ.

Lỗi lint API không ổn định

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.

Chú thích @UnstableApi không ngụ ý gì về chất lượng hoặc hiệu suất của một API, mà chỉ cho biết rằng API đó không phải là "API cố định".

Bạn có 2 lựa chọn để xử lý lỗi lint API không ổn định:

  • Chuyển sang sử dụng một API ổn định để đạt được kết quả tương tự.
  • Tiếp tục sử dụng API không ổn định và chú thích việc sử dụng bằng @OptIn, như minh hoạ sau.
Thêm chú thích @OptIn

Android Studio có thể giúp bạn thêm chú thích:

Ảnh chụp màn hình: Cách thêm chú thích Chọn nhận
Hình 2: Thêm chú thích @androidx.annotations.OptIn bằng Android Studio.

Bạn cũng có thể chú thích thủ công các vị trí sử dụng cụ thể trong Kotlin:

import androidx.annotation.OptIn
import androidx.media3.common.util.UnstableApi

@OptIn(UnstableApi::class)
fun functionUsingUnstableApi() { ... }

Và cả trong Java:

import androidx.annotation.OptIn;
import androidx.media3.common.util.UnstableApi;

@OptIn(markerClass = UnstableApi.class)
private void methodUsingUnstableApis() { ... }

Bạn có thể chọn sử dụng toàn bộ gói bằng cách thêm tệp package-info.java:

@OptIn(markerClass = UnstableApi.class)
package name.of.your.package;

import androidx.annotation.OptIn;
import androidx.media3.common.util.UnstableApi;

Bạn có thể chọn sử dụng cho toàn bộ dự án bằng cách bỏ qua lỗi lint cụ thể trong tệp lint.xml:

 <?xml version="1.0" encoding="utf-8"?>
 <lint>
   <issue id="UnsafeOptInUsageError">
     <option name="opt-in" value="androidx.media3.common.util.UnstableApi" />
   </issue>
 </lint>

Ngoài ra, còn có chú thích kotlin.OptIn mà bạn không nên dùng. Bạn cần sử dụng chú thích androidx.annotation.OptIn.