تقليل حجم تطبيقك

غالبًا ما يتجنّب المستخدمون تنزيل التطبيقات التي تبدو كبيرة جدًا، لا سيما في الأسواق الناشئة التي الاتصال بشبكات الجيل الثاني والثالث غير المستقرة أو العمل على الخطط ذات الحدود القصوى للبيانات. توضّح هذه الصفحة كيفية تقليل حجم تنزيل تطبيقك، ما يتيح للمزيد من المستخدمين تنزيل تطبيقك.

تحميل تطبيقك باستخدام حِزم تطبيق Android

يجب تحميل تطبيقك بتنسيق مجموعة حزمات تطبيق Android إلى التطبيق على الفور. حفظ حجم التطبيق عند نشره على Google Play "مجموعة حزمات تطبيق Android" هي تنسيق تحميل يتضمّن جميع الرموز والموارد التي تم تجميعها لتطبيقك ولكنها تؤخر إنشاء ملفات APK وتسجيل الدخول إليها في Google Play.

يستخدم نموذج عرض التطبيقات في Google Play بعد ذلك حِزمة تطبيقك لإنشاء وعرض حِزم APK محسّنة. ضبط إعدادات الجهاز لكل مستخدم كي ينزّل الرمز والموارد التي يحتاج إليها فقط تشغيل تطبيقك. لست مضطرًا إلى إنشاء عدة حِزم APK وتوقيعها وإدارتها للتوافق مع الأجهزة المختلفة والحصول على عمليات تنزيل أصغر حجمًا وأكثر تحسنًا.

يفرض Google Play تنزيلًا مضغوطًا قيد الحجم بمقدار 200 ميغابايت للتطبيقات التي يتم نشرها باستخدام حِزم التطبيقات. يمكن استخدام ميزتَي "عرض الميزات في Play" و"عرض مواد العرض في Play" لتوفير أحجام أكبر، ولكن يمكن أن تؤدي زيادة حجم تطبيقك إلى التأثير سلبًا في نجاح عملية التثبيت وزيادة عمليات إلغاء التثبيت، لذا ننصحك بتطبيق الإرشادات الموضّحة في هذه الصفحة لتقليل حجم تنزيل تطبيقك قدر الإمكان.

التعرّف على بنية APK

قبل تقليل حجم تطبيقك، من المفيد فهم بنية ملف APK للتطبيق. يتألّف ملف APK من أرشيف ZIP يحتوي على جميع الملفات التي تتألف منها تطبيقك. هذه ملفات فئة Java وملفات الموارد وملفًا يحتوي على موارد مجمعة.

تحتوي حزمة APK على الأدلة التالية:

  • META-INF/: يحتوي على التوقيعين CERT.SF وCERT.RSA بالإضافة إلى ملف البيان MANIFEST.MF.
  • assets/: يحتوي على مواد عرض التطبيق التي يمكن للتطبيق استرجاعها باستخدام عنصر AssetManager .
  • res/: يحتوي على موارد لم يتم تجميعها في resources.arsc
  • lib/: يحتوي على الرمز البرمجي الخاص بطبقة البرنامج معالج البيانات. يحتوي هذا الدليل على دليل فرعي لكل نوع من أنواع المنصات، مثل armeabi وarmeabi-v7a وarm64-v8a وx86، x86_64 وmips.

تحتوي حزمة APK أيضًا على الملفات التالية. فقط AndroidManifest.xml إلزامية:

  • resources.arsc: يحتوي على موارد مجمّعة. يحتوي هذا الملف على محتوى XML من جميع عمليات الضبط في مجلد res/values/. تستخرج أداة التغليف هذا تنسيق XML، وتحويله إلى نموذج ثنائي، وأرشفة المحتوى. ويشمل هذا المحتوى سلاسل resources.arsc والتنسيقات اللغوية، بالإضافة إلى مسارات إلى المحتوى غير المضمّن مباشرةً في ملفresources.arsc، مثل ملفات التنسيق والصور.
  • classes.dex: يحتوي على الفئات التي تم تجميعها بتنسيق ملف DEX الذي يفهمه الجهاز الافتراضي Dalvik أو ART.
  • AndroidManifest.xml: يحتوي على ملف بيان Android الأساسي. يسرد هذا الملف الاسم وإصداره وحقوق الوصول إليه وملفات المكتبة المرجعية للتطبيق. يستخدم الملف واجهة برمجة تطبيقات تنسيق XML الثنائي.

تقليل عدد الموارد وحجمها

يؤثر حجم حزمة APK في سرعة تحميل تطبيقك وكمية الذاكرة التي يستخدمها ومقدار الطاقة التي يستهلكها. يمكنك تصغير حزمة APK عن طريق تقليل عدد ملفات والموارد التي تحتوي عليها. على وجه الخصوص، يمكنك إزالة الموارد التي لم يعُد تطبيقك يستخدمها، ويمكنك استخدام عناصر Drawable قابلة للتحجيم بدلاً من ملفات الصور. يتناول هذا القسم هذه الطرق وطرقًا أخرى يمكنك من خلالها تقليل الموارد في تطبيقك لتقليل الحجم الإجمالي لحزمة APK.

إزالة الموارد غير المستخدَمة

أداة lint: أداة لتحليل الرموز البرمجية الثابتة مضمّنة في "استوديو Android": ترصد الموارد في مجلد res/ التي لا يشير إليه. عندما تكتشف أداة lint موردًا يُحتمل أن يكون غير مستخدم في فإنها تطبع رسالة مثل المثال التالي:

res/layout/preferences.xml: Warning: The resource R.layout.preferences appears
    to be unused [UnusedResources]

قد تتضمّن المكتبات التي تضيفها إلى الرمز المبرمَج موارد غير مستخدَمة. يمكن لنظام Gradle التلقائي إزالة الموارد نيابةً عنك في حال تفعيل الميزة shrinkResources في ملف build.gradle.kts للتطبيق.

Kotlinرائع
android {
    // Other settings.

    buildTypes {
        getByName("release") {
            minifyEnabled = true
            shrinkResources = true
            proguardFiles(getDefaultProguardFile('proguard-android.txt'), "proguard-rules.pro")
        }
    }
}
android {
    // Other settings.

    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

لاستخدام shrinkResources، فعِّل ميزة تصغير حجم الرموز. أثناء عملية التصميم، يكون R8 أولاً لإزالة الرمز البرمجي غير المستخدَم بعد ذلك، يزيل المكوّن الإضافي لنظام Gradle المتوافق مع Android الموارد غير المستخدَمة.

للاطّلاع على مزيد من المعلومات حول الرموز البرمجية وموارد تقليص الموارد، والطرق الأخرى التي يتّبعها "استوديو Android" لتقليل حزمة APK، يُرجى الاطّلاع على تصغير تطبيقك وإخفاء مفاتيح فك تشفيره وتحسينه.

في الإصدار 7.0 من المكوّن الإضافي لنظام Gradle المتوافق مع Android والإصدارات الأحدث، يمكنك توضيح الإعدادات التي ضبطها تطبيقك. والدعم. يقوم Gradle بتمرير هذه المعلومات إلى نظام التصميم باستخدام resourceConfigurations النكهة وخيار defaultConfig. ثم يمنع نظام التصميم الموارد من ظهور إعدادات أخرى غير متوافقة في حزمة APK، ما يقلّل من حجم حِزمة APK. لمزيد من المعلومات عن هذه الميزة، يُرجى الاطّلاع على مقالة إزالة موارد الترجمة والشرح البديلة غير المستخدَمة .

تقليل استخدام الموارد من المكتبات

عند تطوير تطبيق Android، يتم عادةً استخدام مكتبات خارجية لتحسين مستوى سهولة الاستخدام والتنوع. على سبيل المثال، يمكنك الإشارة إلى AndroidX لتحسين تجربة المستخدم على الأجهزة القديمة، أو يمكنك استخدام خدمات Google Play لاسترداد translationsتلقائي للنص في تطبيقك.

إذا كانت المكتبة مصمّمة لخادم أو كمبيوتر مكتبي، يمكن أن تتضمّن العديد من العناصر والأساليب التي لا يحتاج إليها تطبيقك. لتضمين أجزاء المكتبة التي يحتاجها تطبيقك فقط، يمكنك تعديل إلى ملفات المكتبة إذا كان الترخيص يتيح لك تعديل المكتبة. يمكنك أيضًا استخدام بديل، مكتبة متوافقة مع الأجهزة الجوّالة لإضافة وظائف محددة إلى تطبيقك.

فك ترميز الصور المتحركة المدمجة مع المحتوى

في الإصدار 12 من نظام التشغيل Android (المستوى 31 من واجهة برمجة التطبيقات)، تم توسيع نطاق واجهة برمجة التطبيقات NDK ImageDecoder لفك ترميز جميع اللقطات وبيانات التوقيت من الصور التي تستخدم تنسيقَي ملفات GIF وWebP المتحرّكين.

يمكنك استخدام ImageDecoder بدلاً من مكتبات الجهات الخارجية لإجراء المزيد من المهام تقليل حجم APK والاستفادة من الميزات المستقبلية التحديثات المتعلقة بالأمان والأداء.

لمزيد من التفاصيل حول واجهة برمجة تطبيقات ImageDecoder، يمكنك الاطّلاع على API reference و عيّنة على GitHub.

إتاحة استخدام كثافات معيّنة فقط

يتوافق Android مع كثافات الشاشة المختلفة، على سبيل المثال ما يلي:

  • ldpi
  • mdpi
  • tvdpi
  • hdpi
  • xhdpi
  • xxhdpi
  • xxxhdpi

على الرغم من أنّ نظام التشغيل Android متوافق مع كثافات الشاشة السابقة، ليس عليك تصدير مواد العرض الممسوحة ضوئيًا لكل كثافة شاشة.

إذا كنت تعلم أنّ نسبة ضئيلة من المستخدمين هي أجهزة ذات كثافات معيّنة، عليك مراعاة ما إذا كنت بحاجة إلى تجميع قيم الكثافات هذه في تطبيقك. في حال عدم تضمين الموارد لكثافة شاشة معيّنة، يعمل Android تلقائيًا على قياس الموارد الحالية التي تم تصميمها في الأصل للتعرّف على كثافات الشاشات الأخرى.

إذا كان تطبيقك يحتاج فقط إلى صور بأحجام مختلفة، يمكنك توفير مساحة أكبر من خلال توفُّر خيار واحد من صورة في drawable-nodpi/. ننصحك بتضمين xxhdpi على الأقل. نسخة الصورة في تطبيقك

لمزيد من المعلومات عن كثافة الشاشة، يُرجى الاطّلاع على أحجام الشاشة وكثافاتها:

استخدام عناصر قابلة للرسم

لا تتطلب بعض الصور مورد صور ثابتة. يمكن أن يرسم إطار العمل الصورة بشكل ديناميكي في وقت التشغيل بدلاً من ذلك Drawable عنصرًا - أو <shape> بوصة XML: يمكن أن يشغل مساحة صغيرة في حزمة APK. بالإضافة إلى ذلك، يمكن استخدام XML Drawable. تنتج صورًا أحادية اللون متوافقة مع إرشادات التصميم المتعدد الأبعاد.

إعادة استخدام المراجع

يمكنك تضمين مورد منفصل لأشكال مختلفة من الصورة، مثل نُسخ مظلّلة أو مُلوّنة أو مُديرة من الصورة نفسها. ومع ذلك، ننصحك بإعادة استخدام مجموعة الموارد نفسها. وتخصيصها حسب الحاجة في وقت التشغيل

يوفر Android العديد من الأدوات المساعدة لتغيير لون أحد الأصول، سواء باستخدام السمتان android:tint وtintMode

ويمكنك أيضًا حذف الموارد التي لا تمثل سوى مكافئ تم تدويره لمورد آخر. ما يلي: مقتطف الرمز مثالاً على "التحسين" في رقصة لا تُنسى من خلال التركيز على منتصف الصورة وتدويرها 180 درجة:

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/ic_thumb_up"
    android:pivotX="50%"
    android:pivotY="50%"
    android:fromDegrees="180" />

العرض من الرمز

يمكنك أيضًا تقليل حجم حزمة APK من خلال عرض صورك بشكلٍ آلي. العرض الإجرائي إخلاء بعض المساحة لأنّك لم تعُد تخزّن ملف صورة في حِزمة APK.

معالجة ملفات PNG

يمكن لأداة aapt تحسين موارد الصور الموضوعة في res/drawable/. مع الضغط بدون فقدان البيانات أثناء عملية التصميم. على سبيل المثال، يمكن لأداة aapt تحويل ملف PNG بألوان حقيقية لا يتطلب أكثر من 256 لونًا إلى ملف PNG بسعة 8 بت مع لوحة ألوان. ينتج عن ذلك الحصول على صورة بجودة متساوية لكن مع مساحة أصغر للذاكرة.

تخضع "aapt" للقيود التالية:

  • لا تقلّص أداة aapt ملفات PNG المضمّنة في asset/. المجلد.
  • يجب أن تستخدم ملفات الصور 256 لونًا أو أقل لكي تتمكّن أداة aapt من تحسين هذه الملفات.
  • قد تؤدي أداة aapt إلى تضخيم ملفات PNG التي سبق ضغطها. لمنع التالي، يمكنك استخدام العلامة isCrunchPngs لإيقاف هذه العملية لملفات PNG:
  • Kotlinرائع
        buildTypes.all { isCrunchPngs = false }
        
        buildTypes.all { isCrunchPngs = false }
        

ضغط ملفات PNG وJPEG

يمكنك تقليل أحجام ملفات PNG بدون فقدان جودة الصورة باستخدام أدوات مثل pngcrush، pngquant أو zopflipng. يمكن لجميع هذه الأدوات تقليل حجم ملف PNG مع الحفاظ على جودة الصورة المرئية.

وتُعدّ أداة pngcrush فعالة بشكل خاص. تتكرر هذه الأداة على فلاتر PNG zlib (Deflate)، باستخدام كل مجموعة من الفلاتر والمعلمات لضغط الصورة. ثم تختار التكوين الذي ينتج عنه أصغر إخراج مضغوط.

لضغط ملفات JPEG، يمكنك استخدام أدوات مثل packJPG وguetzli.

استخدام تنسيق ملف WebP

بدلاً من استخدام ملفات PNG أو JPEG، يمكنك أيضًا استخدام تنسيق ملف WebP لصورك. تنسيق WebP يوفر الضغط مع فقدان البيانات والشفافية، مثل JPG وPNG، ويمكن أن يوفر ضغطًا من تنسيق JPEG أو PNG.

يمكنك تحويل صور BMP أو JPG أو PNG أو صور GIF ثابتة حالية إلى تنسيق WebP باستخدام Android Studio. لمعرفة مزيد من المعلومات، يُرجى الاطّلاع على إنشاء صور WebP.

استخدام الرسومات المتجهة

يمكنك استخدام الرسومات المتجهة لإنشاء رموز مستقلة عن الدقة ووسائط أخرى قابلة للتطوير. يمكنك استخدام هذه الرسومات لتقليل مساحة APK بشكل كبير. يتم تمثيل الصور المتجهة في Android على هيئة VectorDrawable كائنات. باستخدام عنصر VectorDrawable، يمكن لملف بحجم 100 بايت إنشاء صورة حادة بحجم الشاشة.

ومع ذلك، يستغرق النظام وقتًا أطول بكثير لعرض كل عنصر VectorDrawable، وستستغرق الصور الأكبر حجمًا وقتًا أطول للظهور على الشاشة. لذلك، ننصحك بعدم استخدام هذه الرسومات إلا عند عرض صور صغيرة.

لمزيد من المعلومات عن التعامل مع عناصر VectorDrawable، يُرجى الاطّلاع على عناصر الرسم.

استخدام الرسومات المتجهّة للصور المتحركة

عدم الاستخدام AnimationDrawable إنشاء رسوم متحركة على أساس كل إطار، لأن ذلك يتطلب تضمين صورة نقطية منفصلة لكل إطار من الصور المتحركة، مما يؤدي إلى زيادة حجم APK بشكلٍ كبير.

بدلاً من ذلك، استخدم AnimatedVectorDrawableCompat لإنشاء متّجه متحرك القابلة للرسم.

تقليل الرموز البرمجية الأصلية ورمز Java

يمكنك استخدام الطرق التالية لتقليل حجم جافا وقاعدة التعليمات البرمجية الأصلية في التطبيق.

إزالة الرمز الذي تم إنشاؤه غير الضروري

احرص على فهم مساحة أي رمز يتم إنشاؤه تلقائيًا. على سبيل المثال: فإن العديد من أدوات مخزن البروتوكولات المؤقت تنشئ عددًا كبيرًا جدًا من الأساليب والفئات، مما قد يؤدي إلى مضاعفة زيادة حجم تطبيقك بمقدار ثلاثة أضعاف

تجنُّب التعداد

يمكن أن يضيف تعداد واحد حوالي 1.0 إلى 1.4 كيلوبايت إلى ملف classes.dex لتطبيقك. هذه يمكن أن تتراكم الإضافات بسرعة للأنظمة المعقدة أو المكتبات المشتركة. إذا أمكن، ضع في اعتبارك باستخدام تعليق @IntDef التوضيحي وتقليص الرموز لإزالة التعدادات وتحويلها إلى أعداد صحيحة. يحافظ هذا النوع من الإحالات الناجحة على كل الكتابة وفوائد السلامة للتعدادات.

تقليل حجم الملفات الثنائية الأصلية

إذا كان تطبيقك يستخدم رمزًا أصليًا ومجموعة تطوير البرامج (NDK) لنظام التشغيل Android، يمكنك أيضًا تقليل حجم إصدار الإصدار المُعدّ للنشر من تطبيقك من خلال تحسين الرمز البرمجي. هناك طريقتان مفيدتان هما إزالة رموز تصحيح الأخطاء وعدم استخراج المكتبات الأصلية.

إزالة رموز تصحيح الأخطاء

يكون استخدام رموز تصحيح الأخطاء منطقيًا إذا كان تطبيقك لا يزال قيد التطوير ويحتاج إلى تصحيح الأخطاء. استخدِم أداة arm-eabi-strip المقدَّمة في حزمة تطوير البرامج (NDK) لنظام التشغيل Android لإزالة رموزها غير الضرورية لتحديد الأخطاء وحلّها من المكتبات الأصلية. بعد ذلك، يمكنك تجميع إصدار الإصدار.

تجنُّب استخراج المكتبات المجمّعة من رموز برمجية أصلية

عند إنشاء إصدار التطبيق العلني، يمكنك حزم ملفات .so غير المضغوطة في ملف APK من خلال ضبط قيمة useLegacyPackaging على false في ملف build.gradle.kts الخاص بتطبيقك. يؤدي إيقاف هذه العلامة إلى منع PackageManager من نسخ .so ملف من حزمة APK إلى نظام الملفات أثناء التثبيت. هذه الطريقة تجعل حجم تحديثات التطبيق.

الاحتفاظ بحِزم APK متعددة

قد تحتوي حزمة APK على محتوى ينزّله المستخدمون ولا يستخدمونه أبدًا، مثل لغة إضافية أو كثافة كل شاشة. للمساعدة في ضمان حصول المستخدمين على أقل عملية تنزيل، حمِّل تطبيقك إلى Google Play يستخدم مجموعات حزمات تطبيق Android. يتيح تحميل حِزم التطبيقات لـ Google Play إنشاء حِزم APK محسّنة وعرضها لكل إعدادات جهاز المستخدم، ما يسمح للمستخدمين بتنزيل الرمز البرمجي والموارد التي يحتاجون إليها فقط لتشغيل تطبيقك. ولن يكون عليك إنشاء حِزم APK متعددة وتوقيعها وإدارتها لتتوافق مع الأجهزة المختلفة، وسيحصل المستخدمون على عمليات تنزيل أصغر حجمًا وأكثر تحسينًا.

إذا كنت لا تنشر تطبيقك على Google Play، يمكنك تقسيم تطبيقك إلى عدة حِزم APK، وتمييزها حسب عوامل مثل حجم الشاشة أو مدى توافقها مع وحدة معالجة الرسومات.

عندما ينزِّل مستخدم تطبيقك، يتلقّى جهازه حزمة APK الصحيحة استنادًا إلى ميزات الجهاز وإعداداته. بهذه الطريقة، لا تتلقّى الأجهزة مواد عرض للميزات التي لا تملكها. على سبيل المثال، إذا كان لدى المستخدم جهاز hdpi، لن يحتاج إلى xxxhdpi موارد قد تُدرِجها للأجهزة التي تتضمّن شاشات ذات كثافة أعلى.

لمزيد من المعلومات، يُرجى الاطّلاع على مقالتَي إنشاء عدة APK وإتاحة حِزم APK متعددة.