צמצום הגודל של חבילת ה-APK הוא היבט חשוב בפיתוח אפליקציית Android טובה. זה נכון במיוחד כשמטרגטים שווקים מתפתחים, וגם כשמפתחים אפליקציה ללא התקנה ל-Android. במקרים כאלה, כדאי לצמצם את הגודל של ספריית ExoPlayer שנכללת בחבילת ה-APK. בדף הזה מפורטים כמה שלבים פשוטים שיעזרו לכם להשיג את המטרה הזו.
שימוש רק בתלות הנדרשת
להסתמך רק על מודולי הספרייה שבאמת נחוצים. לדוגמה, הקוד הבא יוסיף יחסי תלות במודולים של ספריות ExoPlayer, DASH ו-UI, כפי שנדרש באפליקציה שמפעילה רק תוכן DASH:
Kotlin
implementation("androidx.media3:media3-exoplayer:1.9.2") implementation("androidx.media3:media3-exoplayer-dash:1.9.2") implementation("androidx.media3:media3-ui:1.9.2")
Groovy
implementation "androidx.media3:media3-exoplayer:1.9.2" implementation "androidx.media3:media3-exoplayer-dash:1.9.2" implementation "androidx.media3:media3-ui:1.9.2"
הפעלה של כיווץ קוד ומשאבים
מומלץ להפעיל כיווץ של קוד ומשאבים בגרסאות ה-build של האפליקציה שמוכנות להפצה. המבנה של ExoPlayer מאפשר כיווץ קוד כדי להסיר ביעילות פונקציונליות שלא נמצאת בשימוש. לדוגמה, באפליקציה שמפעילה תוכן DASH, אפשר להקטין את התרומה של ExoPlayer לגודל ה-APK בכ-40% על ידי הפעלת צמצום קוד.
במאמר כיווץ, ערפול ואופטימיזציה של האפליקציה מוסבר איך להפעיל כיווץ של קוד ומשאבים.
ציון הרכיבים לעיבוד שהאפליקציה צריכה
כברירת מחדל, מעבדי הנתונים של הנגן ייווצרו באמצעות DefaultRenderersFactory. DefaultRenderersFactory תלוי בכל ההטמעות של Renderer שמופיעות בספריית ExoPlayer, ולכן אף אחת מהן לא תוסר על ידי צמצום הקוד. אם אתם יודעים שהאפליקציה שלכם צריכה רק קבוצת משנה של רכיבי עיבוד, אתם יכולים לציין במקום זאת את רכיבי העיבוד שלכם RenderersFactory. לדוגמה, אפליקציה שמפעילה רק אודיו יכולה להגדיר מפעל כמו זה כשיוצרים מופעים של 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();
כך אפשר יהיה להסיר הטמעות אחרות של Renderer באמצעות צמצום קוד. בדוגמה הספציפית הזו, רכיבי העיבוד של הטקסט והמטא-נתונים מוסרים (מה שאומר שהנגן לא יעבד או ישדר כתוביות או מטא-נתונים בתוך הסטרימינג (למשל, ICY)).
מציינים אילו מחלצי נתונים נדרשים לאפליקציה
כברירת מחדל, הנגן יוצר מופעים של Extractor כדי להפעיל מדיה מתקדמת באמצעות DefaultExtractorsFactory. DefaultExtractorsFactory תלוי בכל ההטמעות של Extractor שמופיעות בספריית ExoPlayer, ולכן אף אחת מהן לא תוסר על ידי צמצום הקוד. אם אתם יודעים שהאפליקציה שלכם צריכה להפעיל רק מספר קטן של פורמטים של קונטיינרים, או שהיא לא מפעילה מדיה פרוגרסיבית בכלל, אתם יכולים לציין במקום זאת את ExtractorsFactory שלכם. לדוגמה,
אפליקציה שצריכה רק להפעיל קובצי mp4 יכולה לספק מפעל כמו:
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 בהתאמה אישית
אם האפליקציה משתמשת ב-MediaSource.Factory מותאם אישית ואתם רוצים ש-DefaultMediaSourceFactory יוסר באמצעות הסרת קוד, אתם צריכים להעביר את MediaSource.Factory ישירות אל ה-constructor של ExoPlayer.Builder.
Kotlin
val player = ExoPlayer.Builder(context, customMediaSourceFactory).build()
Java
ExoPlayer player = new ExoPlayer.Builder(context, mediaSourceFactory).build();
אם האפליקציה שלכם משתמשת ישירות ב-MediaSource במקום ב-MediaItem, אתם צריכים להעביר את MediaSource.Factory.UNSUPPORTED אל ה-constructor של 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));