การย่อ APK
จัดทุกอย่างให้เป็นระเบียบอยู่เสมอด้วยคอลเล็กชัน
บันทึกและจัดหมวดหมู่เนื้อหาตามค่ากำหนดของคุณ
การลดขนาด APK เป็นสิ่งสำคัญในการพัฒนาแอป Android ที่ดี
โดยเฉพาะอย่างยิ่งเมื่อกำหนดเป้าหมายเป็นตลาดเกิดใหม่และ
เมื่อพัฒนา Android Instant App ในกรณีดังกล่าว คุณอาจต้องการ
ลดขนาดของไลบรารี ExoPlayer ที่รวมอยู่ใน APK หน้านี้จะอธิบายขั้นตอนง่ายๆ ที่จะช่วยให้คุณทำเช่นนี้ได้
ใช้เฉพาะการขึ้นต่อกันที่จำเป็น
ใช้เฉพาะโมดูลไลบรารีที่คุณต้องการจริงๆ เท่านั้น ตัวอย่างเช่น
รายการต่อไปนี้จะเพิ่มทรัพยากร Dependency ในโมดูล ExoPlayer, DASH และไลบรารี UI
ตามที่อาจจำเป็นสำหรับแอปที่เล่นเนื้อหา DASH เท่านั้น
Kotlin
implementation("androidx.media3:media3-exoplayer:1.8.0")
implementation("androidx.media3:media3-exoplayer-dash:1.8.0")
implementation("androidx.media3:media3-ui:1.8.0")
Groovy
implementation "androidx.media3:media3-exoplayer:1.8.0"
implementation "androidx.media3:media3-exoplayer-dash:1.8.0"
implementation "androidx.media3:media3-ui:1.8.0"
เปิดใช้การย่อโค้ดและทรัพยากร
คุณควรเปิดใช้การลดขนาดโค้ดและทรัพยากรสำหรับบิลด์ที่เผยแพร่ของแอป
ExoPlayer มีโครงสร้างที่ช่วยให้การลดขนาดโค้ดสามารถ
นำฟังก์ชันการทำงานที่ไม่ได้ใช้ออกได้อย่างมีประสิทธิภาพ ตัวอย่างเช่น สำหรับแอปที่
เล่นเนื้อหา DASH การเปิดใช้การลดขนาดโค้ดจะช่วยลดขนาด APK ของ ExoPlayer ได้ประมาณ 40%
อ่านลดขนาด สร้างความสับสน และเพิ่มประสิทธิภาพแอปเพื่อดูวิธีเปิดใช้การลดขนาดโค้ดและทรัพยากร
ระบุตัวแสดงผลที่แอปของคุณต้องการ
โดยค่าเริ่มต้น ระบบจะสร้างตัวแสดงผลของเพลเยอร์โดยใช้
DefaultRenderersFactory
DefaultRenderersFactory
ขึ้นอยู่กับการใช้งาน Renderer
ทั้งหมดที่ระบุไว้ในไลบรารี ExoPlayer และด้วยเหตุนี้
ระบบจะไม่นำการใช้งานใดๆ ออกโดยการลดขนาดโค้ด หากทราบว่าแอปของคุณต้องการเพียงชุดย่อยของโปรแกรมแสดงผล คุณสามารถระบุRenderersFactory
ของคุณเองแทนได้
ตัวอย่างเช่น แอปที่เล่นเฉพาะเสียงสามารถกำหนด Factory ได้ดังนี้เมื่อสร้างอินสแตนซ์ 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();
ซึ่งจะช่วยให้โค้ด
shrinking นำการติดตั้งใช้งาน Renderer
อื่นๆ ออกได้ ในวิดีโอตัวอย่างนี้ ระบบจะนำโปรแกรมแสดงข้อความและข้อมูลเมตาออก (ซึ่งหมายความว่าเพลเยอร์จะไม่ประมวลผลหรือส่งออกคำบรรยายแทนเสียงหรือข้อมูลเมตาในสตรีม (เช่น ICY))
โดยค่าเริ่มต้น เพลเยอร์จะสร้างอินสแตนซ์ Extractor
เพื่อเล่นสื่อแบบโปรเกรสซีฟโดยใช้
DefaultExtractorsFactory
DefaultExtractorsFactory
ขึ้นอยู่กับการใช้งาน Extractor
ทั้งหมดที่ระบุไว้ในไลบรารี ExoPlayer และด้วยเหตุนี้
ระบบจะไม่นำการใช้งานใดๆ ออกโดยการลดขนาดโค้ด หากทราบว่าแอปของคุณต้องการเล่นเฉพาะรูปแบบคอนเทนเนอร์จำนวนเล็กน้อย หรือไม่เล่นสื่อแบบ Progressive เลย คุณสามารถระบุ ExtractorsFactory
ของคุณเองแทนได้ ตัวอย่างเช่น
แอปที่ต้องการเล่นเฉพาะไฟล์ mp4 สามารถระบุ Factory ได้ดังนี้
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();
ซึ่งจะช่วยให้สามารถนำการติดตั้งใช้งาน Extractor
อื่นๆ ออกได้โดยการลดขนาดโค้ด ซึ่งอาจส่งผลให้ขนาดลดลงอย่างมาก
หากแอปไม่เล่นเนื้อหาแบบค่อยๆ ดาวน์โหลดเลย คุณควรส่ง
ExtractorsFactory.EMPTY
ไปยังตัวสร้าง DefaultMediaSourceFactory
จากนั้น
ส่ง mediaSourceFactory
ไปยังตัวสร้าง 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();
หากแอปใช้ MediaSource.Factory
ที่กำหนดเองและคุณต้องการ
DefaultMediaSourceFactory
ที่จะนำออกโดยการลบโค้ด คุณควรส่ง MediaSource.Factory
ไปยังตัวสร้าง ExoPlayer.Builder
โดยตรง
Kotlin
val player = ExoPlayer.Builder(context, customMediaSourceFactory).build()
Java
ExoPlayer player = new ExoPlayer.Builder(context, mediaSourceFactory).build();
หากแอปใช้ MediaSource
โดยตรงแทน MediaItem
คุณควรส่ง MediaSource.Factory.UNSUPPORTED
ไปยังตัวสร้าง ExoPlayer.Builder
เพื่อให้มั่นใจว่าการลดขนาดโค้ดจะสามารถลบ DefaultMediaSourceFactory
และ DefaultExtractorsFactory
ออกได้
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));
ตัวอย่างเนื้อหาและโค้ดในหน้าเว็บนี้ขึ้นอยู่กับใบอนุญาตที่อธิบายไว้ในใบอนุญาตการใช้เนื้อหา Java และ OpenJDK เป็นเครื่องหมายการค้าหรือเครื่องหมายการค้าจดทะเบียนของ Oracle และ/หรือบริษัทในเครือ
อัปเดตล่าสุด 2025-08-27 UTC
[[["เข้าใจง่าย","easyToUnderstand","thumb-up"],["แก้ปัญหาของฉันได้","solvedMyProblem","thumb-up"],["อื่นๆ","otherUp","thumb-up"]],[["ไม่มีข้อมูลที่ฉันต้องการ","missingTheInformationINeed","thumb-down"],["ซับซ้อนเกินไป/มีหลายขั้นตอนมากเกินไป","tooComplicatedTooManySteps","thumb-down"],["ล้าสมัย","outOfDate","thumb-down"],["ปัญหาเกี่ยวกับการแปล","translationIssue","thumb-down"],["ตัวอย่าง/ปัญหาเกี่ยวกับโค้ด","samplesCodeIssue","thumb-down"],["อื่นๆ","otherDown","thumb-down"]],["อัปเดตล่าสุด 2025-08-27 UTC"],[],[],null,["# APK shrinking\n\nMinimizing APK size is an important aspect of developing a good Android\napp. This is particularly true when targeting developing markets, and\nalso when developing an Android Instant App. For such cases, it may be desirable\nto minimize the size of the ExoPlayer library that's included in the APK. This\npage outlines some simple steps that can help to achieve this.\n\nUse only required dependencies\n------------------------------\n\nDepend only on the library modules that you actually need. For example, the\nfollowing will add dependencies on the ExoPlayer, DASH, and UI library modules,\nas might be required for an app that only plays DASH content: \n\n### Kotlin\n\n```kotlin\nimplementation(\"androidx.media3:media3-exoplayer:1.8.0\")\nimplementation(\"androidx.media3:media3-exoplayer-dash:1.8.0\")\nimplementation(\"androidx.media3:media3-ui:1.8.0\")\n```\n\n### Groovy\n\n```groovy\nimplementation \"androidx.media3:media3-exoplayer:1.8.0\"\nimplementation \"androidx.media3:media3-exoplayer-dash:1.8.0\"\nimplementation \"androidx.media3:media3-ui:1.8.0\"\n```\n\nEnable code and resource shrinking\n----------------------------------\n\nYou should enable code and resource shrinking for your app's release\nbuilds. ExoPlayer is structured in a way that allows code shrinking to\neffectively remove unused functionality. For example, for an app that\nplays DASH content, ExoPlayer's contribution to APK size can be reduced by\napproximately 40% by enabling code shrinking.\n\nRead [Shrink, obfuscate, and optimize your app](/studio/build/shrink-code) to learn how to enable\ncode and resource shrinking.\n\nSpecify which renderers your app needs\n--------------------------------------\n\nBy default, the player's renderers will be created using\n`DefaultRenderersFactory`. `DefaultRenderersFactory` depends on all of the\n`Renderer` implementations provided in the ExoPlayer library, and as a result\nnone of them will be removed by code shrinking. If you know that your app only\nneeds a subset of renderers, you can specify your own `RenderersFactory`\ninstead. For example, an app that only plays audio can define a factory like\nthis when instantiating `ExoPlayer` instances: \n\n### Kotlin\n\n```kotlin\nval audioOnlyRenderersFactory =\n RenderersFactory {\n handler: Handler,\n videoListener: VideoRendererEventListener,\n audioListener: AudioRendererEventListener,\n textOutput: TextOutput,\n metadataOutput: MetadataOutput,\n -\u003e\n arrayOf\u003cRenderer\u003e(\n MediaCodecAudioRenderer(context, MediaCodecSelector.DEFAULT, handler, audioListener)\n )\n}\nval player = ExoPlayer.Builder(context, audioOnlyRenderersFactory).build()\n```\n\n### Java\n\n```java\nRenderersFactory audioOnlyRenderersFactory =\n (handler, videoListener, audioListener, textOutput, metadataOutput) -\u003e\n new Renderer[] {\n new MediaCodecAudioRenderer(\n context, MediaCodecSelector.DEFAULT, handler, audioListener)\n };\nExoPlayer player = new ExoPlayer.Builder(context, audioOnlyRenderersFactory).build();\n```\n\n\u003cbr /\u003e\n\nThis will allow other `Renderer` implementations to be removed by code\nshrinking. In this particular example video, text and metadata renderers are\nremoved (which means any subtitles or in-stream metadata (e.g.\n[ICY](https://cast.readme.io/docs/icy)) won't be processed or emitted by the\nplayer).\n\nSpecify which extractors your app needs\n---------------------------------------\n\nBy default, the player creates `Extractor` instances to play progressive media using\n`DefaultExtractorsFactory`. `DefaultExtractorsFactory` depends on all of the\n`Extractor` implementations provided in the ExoPlayer library, and as a result\nnone of them will be removed by code shrinking. If you know that your app only\nneeds to play a small number of container formats, or doesn't play progressive\nmedia at all, you can specify your own `ExtractorsFactory` instead. For example,\nan app that only needs to play mp4 files can provide a factory like: \n\n### Kotlin\n\n```kotlin\nval mp4ExtractorFactory = ExtractorsFactory {\n arrayOf\u003cExtractor\u003e(Mp4Extractor(DefaultSubtitleParserFactory()))\n}\nval player =\n ExoPlayer.Builder(context, DefaultMediaSourceFactory(context, mp4ExtractorFactory)).build()\n```\n\n### Java\n\n```java\nExtractorsFactory mp4ExtractorFactory =\n () -\u003e new Extractor[] {new Mp4Extractor(new DefaultSubtitleParserFactory())};\nExoPlayer player =\n new ExoPlayer.Builder(context, new DefaultMediaSourceFactory(context, mp4ExtractorFactory))\n .build();\n```\n\n\u003cbr /\u003e\n\nThis will allow other `Extractor` implementations to be removed by code\nshrinking, which can result in a significant reduction in size.\n\nIf your app is not playing progressive content at all, you should pass\n`ExtractorsFactory.EMPTY` to the `DefaultMediaSourceFactory` constructor, then\npass that `mediaSourceFactory` to the `ExoPlayer.Builder` constructor. \n\n### Kotlin\n\n```kotlin\nval player =\n ExoPlayer.Builder(context, DefaultMediaSourceFactory(context, ExtractorsFactory.EMPTY)).build()\n```\n\n### Java\n\n```java\nExoPlayer player =\n new ExoPlayer.Builder(\n context, new DefaultMediaSourceFactory(context, ExtractorsFactory.EMPTY))\n .build();\n```\n\n\u003cbr /\u003e\n\nCustom MediaSource instantiation\n--------------------------------\n\nIf your app is using a custom `MediaSource.Factory` and you want\n`DefaultMediaSourceFactory` to be removed by code stripping, you should pass\nyour `MediaSource.Factory` directly to the `ExoPlayer.Builder` constructor. \n\n### Kotlin\n\n```kotlin\nval player = ExoPlayer.Builder(context, customMediaSourceFactory).build()\n```\n\n### Java\n\n```java\nExoPlayer player = new ExoPlayer.Builder(context, mediaSourceFactory).build();\n```\n\n\u003cbr /\u003e\n\nIf your app is using `MediaSource` directly instead of `MediaItem` you should\npass `MediaSource.Factory.UNSUPPORTED` to the `ExoPlayer.Builder` constructor,\nto ensure `DefaultMediaSourceFactory` and `DefaultExtractorsFactory` can be\nstripped by code shrinking. \n\n### Kotlin\n\n```kotlin\nval player = ExoPlayer.Builder(context, MediaSource.Factory.UNSUPPORTED).build()\nval mediaSource =\n ProgressiveMediaSource.Factory(dataSourceFactory, customExtractorsFactory)\n .createMediaSource(MediaItem.fromUri(uri))\n```\n\n### Java\n\n```java\nExoPlayer player = new ExoPlayer.Builder(context, MediaSource.Factory.UNSUPPORTED).build();\nProgressiveMediaSource mediaSource =\n new ProgressiveMediaSource.Factory(dataSourceFactory, customExtractorsFactory)\n .createMediaSource(MediaItem.fromUri(uri));\n```\n\n\u003cbr /\u003e"]]