Rút gọn APK

Giảm thiểu kích thước APK là một khía cạnh quan trọng khi phát triển một ứng dụng Android tốt. Điều này đặc biệt đúng khi nhắm đến các thị trường đang phát triển, cũng như khi phát triển một Ứng dụng tức thì trên Android. Trong những trường hợp như vậy, bạn nên giảm thiểu kích thước của thư viện ExoPlayer có trong APK. Trang này trình bày một số bước đơn giản có thể giúp bạn đạt được mục tiêu này.

Chỉ sử dụng các phần phụ thuộc bắt buộc

Chỉ phụ thuộc vào các mô-đun thư viện mà bạn thực sự cần. Ví dụ: đoạn mã sau sẽ thêm các phần phụ thuộc vào các mô-đun ExoPlayer, DASH và thư viện giao diện người dùng, có thể là những mô-đun bắt buộc đối với một ứng dụng chỉ phát nội dung DASH:

Kotlin

implementation("androidx.media3:media3-exoplayer:1.7.1")
implementation("androidx.media3:media3-exoplayer-dash:1.7.1")
implementation("androidx.media3:media3-ui:1.7.1")

Groovy

implementation "androidx.media3:media3-exoplayer:1.7.1"
implementation "androidx.media3:media3-exoplayer-dash:1.7.1"
implementation "androidx.media3:media3-ui:1.7.1"

Bật tính năng giảm kích thước mã và tài nguyên

Bạn nên bật tính năng rút gọn mã và tài nguyên cho các bản phát hành của ứng dụng. ExoPlayer được cấu trúc theo cách cho phép tính năng rút gọn mã loại bỏ hiệu quả chức năng không dùng đến. Ví dụ: đối với một ứng dụng phát nội dung DASH, bạn có thể giảm khoảng 40% mức đóng góp của ExoPlayer vào kích thước APK bằng cách bật tính năng rút gọn mã.

Hãy đọc bài viết Rút gọn, làm rối mã nguồn và tối ưu hoá ứng dụng để tìm hiểu cách bật tính năng rút gọn mã và tài nguyên.

Chỉ định những trình kết xuất mà ứng dụng của bạn cần

Theo mặc định, các trình kết xuất của trình phát sẽ được tạo bằng DefaultRenderersFactory. DefaultRenderersFactory phụ thuộc vào tất cả các phương thức triển khai Renderer có trong thư viện ExoPlayer, do đó, không có phương thức triển khai nào bị xoá bằng cách giảm kích thước mã. Nếu biết rằng ứng dụng của bạn chỉ cần một nhóm nhỏ trình kết xuất, thì bạn có thể chỉ định RenderersFactory của riêng mình. Ví dụ: một ứng dụng chỉ phát âm thanh có thể xác định một phương thức khởi tạo như thế này khi khởi tạo các thực thể ExoPlayer:

Kotlin

val audioOnlyRenderersFactory =
  RenderersFactory {
    handler: Handler,
    videoListener: VideoRendererEventListener,
    audioListener: AudioRendererEventListener,
    textOutput: TextOutput,
    metadataOutput: MetadataOutput,
    ->
    arrayOf<Renderer>(
      MediaCodecAudioRenderer(context, MediaCodecSelector.DEFAULT, handler, audioListener)
    )
}
val player = ExoPlayer.Builder(context, audioOnlyRenderersFactory).build()

Java

RenderersFactory audioOnlyRenderersFactory =
    (handler, videoListener, audioListener, textOutput, metadataOutput) ->
        new Renderer[] {
            new MediaCodecAudioRenderer(
                context, MediaCodecSelector.DEFAULT, handler, audioListener)
        };
ExoPlayer player = new ExoPlayer.Builder(context, audioOnlyRenderersFactory).build();

Điều này sẽ cho phép xoá các phương thức triển khai Renderer khác bằng cách giảm kích thước mã. Trong video ví dụ cụ thể này, trình kết xuất văn bản và siêu dữ liệu sẽ bị xoá (nghĩa là mọi phụ đề hoặc siêu dữ liệu trong luồng phát (ví dụ: ICY) sẽ không được trình phát xử lý hoặc phát ra).

Chỉ định những trình trích xuất mà ứng dụng của bạn cần

Theo mặc định, trình phát sẽ tạo các thực thể Extractor để phát nội dung nghe nhìn tăng tiến bằng cách sử dụng DefaultExtractorsFactory. DefaultExtractorsFactory phụ thuộc vào tất cả các phương thức triển khai Extractor có trong thư viện ExoPlayer, do đó, không có phương thức triển khai nào bị xoá bằng cách giảm kích thước mã. Nếu biết rằng ứng dụng của bạn chỉ cần phát một số ít định dạng vùng chứa hoặc hoàn toàn không phát nội dung nghe nhìn phát trực tuyến, thì bạn có thể chỉ định ExtractorsFactory của riêng mình. Ví dụ: một ứng dụng chỉ cần phát tệp mp4 có thể cung cấp một phương thức khởi tạo như sau:

Kotlin

val mp4ExtractorFactory = ExtractorsFactory {
  arrayOf<Extractor>(Mp4Extractor(DefaultSubtitleParserFactory()))
}
val player =
  ExoPlayer.Builder(context, DefaultMediaSourceFactory(context, mp4ExtractorFactory)).build()

Java

ExtractorsFactory mp4ExtractorFactory =
    () -> new Extractor[] {new Mp4Extractor(new DefaultSubtitleParserFactory())};
ExoPlayer player =
    new ExoPlayer.Builder(context, new DefaultMediaSourceFactory(context, mp4ExtractorFactory))
        .build();

Điều này sẽ cho phép loại bỏ các phương thức triển khai Extractor khác bằng cách giảm kích thước mã, có thể giúp giảm đáng kể kích thước.

Nếu ứng dụng của bạn hoàn toàn không phát nội dung phát trực tuyến từng phần, thì bạn nên truyền ExtractorsFactory.EMPTY đến hàm khởi tạo DefaultMediaSourceFactory, sau đó truyền mediaSourceFactory đến hàm khởi tạo ExoPlayer.Builder.

Kotlin

val player =
  ExoPlayer.Builder(context, DefaultMediaSourceFactory(context, ExtractorsFactory.EMPTY)).build()

Java

ExoPlayer player =
    new ExoPlayer.Builder(
            context, new DefaultMediaSourceFactory(context, ExtractorsFactory.EMPTY))
        .build();

Khởi tạo MediaSource tuỳ chỉnh

Nếu ứng dụng của bạn đang sử dụng MediaSource.Factory tuỳ chỉnh và bạn muốn DefaultMediaSourceFactory bị loại bỏ bằng tính năng loại bỏ mã, bạn nên truyền trực tiếp MediaSource.Factory đến hàm khởi tạo ExoPlayer.Builder.

Kotlin

val player = ExoPlayer.Builder(context, customMediaSourceFactory).build()

Java

ExoPlayer player = new ExoPlayer.Builder(context, mediaSourceFactory).build();

Nếu ứng dụng của bạn đang sử dụng trực tiếp MediaSource thay vì MediaItem, bạn nên truyền MediaSource.Factory.UNSUPPORTED đến hàm khởi tạo ExoPlayer.Builder để đảm bảo tính năng rút gọn mã có thể loại bỏ DefaultMediaSourceFactoryDefaultExtractorsFactory.

Kotlin

val player = ExoPlayer.Builder(context, MediaSource.Factory.UNSUPPORTED).build()
val mediaSource =
  ProgressiveMediaSource.Factory(dataSourceFactory, customExtractorsFactory)
    .createMediaSource(MediaItem.fromUri(uri))

Java

ExoPlayer player = new ExoPlayer.Builder(context, MediaSource.Factory.UNSUPPORTED).build();
ProgressiveMediaSource mediaSource =
    new ProgressiveMediaSource.Factory(dataSourceFactory, customExtractorsFactory)
        .createMediaSource(MediaItem.fromUri(uri));