كيف يعمل تثبيت تطبيقات Android تحت الغطاء

A smartphone on engineering blueprints with gears, illustrating how app installation works

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

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

الخطوة 1: بدء التثبيت

تبدأ عملية التثبيت بشكل مختلف اعتمادًا على المصدر:

  • متجر اللعب: يقوم تطبيق Play Store بتنزيل APK (أو ملفات APK المقسمة) ويستدعي مثبت حزمة النظام بامتيازات خاصة تتجاوز بعض تأكيدات المستخدم.
  • التحميل الجانبي: عند فتح ملف APK، يقوم Android بتشغيل نشاط تثبيت الحزمة. في نظام التشغيل Android 8.0 والإصدارات الأحدث، يجب أن يتمتع تطبيق التثبيت بإذن "تثبيت تطبيقات غير معروفة" لمصدره المحدد.
  • بنك التنمية الآسيوي: يتصل أمر adb install مباشرة بخدمة مدير الحزم عبر USB، متجاوزًا المثبت الرسومي بالكامل.

بغض النظر عن المصدر، تصل جميع التثبيتات في النهاية إلى نفس خدمة النظام: PackageManagerService (PMS). هذه هي السلطة المركزية لجميع عمليات الحزمة على Android.

الخطوة 2: تحليل الحزمة

قبل أي شيء آخر، يحتاج النظام إلى فهم ما هو على وشك تثبيته. تستدعي PackageManagerService PackageParser لقراءة ملف APK واستخراج بيانات التعريف الخاصة به.

يقرأ المحلل اللغوي ملف AndroidManifest.xml من داخل ملف APK. يحتوي ملف XML الثنائي هذا على معلومات مهمة:

  • اسم الحزمة: المعرف الفريد للتطبيق (على سبيل المثال، com.example.myapp)
  • رمز الإصدار واسمه: يُستخدم لتحديد ما إذا كانت هذه ترقية أم تثبيتًا جديدًا
  • الحد الأدنى والهدف لإصدارات SDK: يحدد التوافق مع الجهاز
  • الأذونات المعلنة: كلا الأذونات التي يطلبها التطبيق والأذونات المخصصة التي يحددها
  • المكونات: الأنشطة والخدمات وأجهزة استقبال البث وموفري المحتوى الذين يسجلهم التطبيق
  • متطلبات ميزات الأجهزة والبرامج: مثل الكاميرا أو نظام تحديد المواقع العالمي (GPS) أو إصدارات OpenGL محددة

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

الخطوة 3: اختبارات التوافق

بمجرد تحليل البيان، يقوم النظام بإجراء سلسلة من اختبارات التوافق:

  • نسخة SDK: إذا كان minSdkVersion الخاص بالتطبيق أعلى من مستوى API الخاص بالجهاز، فسيتم رفض التثبيت.
  • توافق أبي: إذا كان ملف APK يحتوي على مكتبات أصلية، فسيقوم النظام بالتحقق مما إذا كانت تتوافق مع بنية وحدة المعالجة المركزية (CPU) الخاصة بالجهاز. لن يتم تثبيت APK الذي يحتوي على مكتبات armeabi-v7a فقط على جهاز يعمل بنظام x86 فقط.
  • الميزات المطلوبة: إذا أعلن التطبيق عن ميزات الأجهزة المطلوبة (مثل android.hardware.telephony، يتحقق النظام من أن الجهاز يدعمها).
  • التخزين المتاح: يتحقق النظام مما إذا كانت هناك مساحة خالية كافية لتثبيت التطبيق، بما في ذلك مساحة للمكتبات الأصلية المستخرجة وملفات DEX المحسنة.

الخطوة 4: التحقق من التوقيع

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

تعتمد عملية التحقق على أنظمة التوقيع الموجودة:

توقيع V1 (توقيع JAR)

يقوم النظام بالتحقق من دليل META-INF/ لملفات التوقيع (.SF أو .RSA أو .DSA). يتم التحقق من كل ملف في APK مقابل الملخصات المدرجة في البيان. وهذا بطيء لأنه يجب تجزئة كل ملف على حدة.

توقيع V2 (نظام توقيع APK v2)

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

توقيع V3 (تدوير المفتاح)

متوفر من Android 9.0، V3 يمتد إلى V2 مع دعم تدوير المفاتيح. وهو يتضمن بنية إثبات التدوير التي تربط مفاتيح التوقيع القديمة والجديدة، مما يسمح للمطورين بتغيير مفتاح التوقيع الخاص بهم مع الحفاظ على توافق التحديث.

توقيع V4 (تزايدي)

قدم Android 11 الإصدار V4 للتثبيتات المتزايدة. فهو يوفر توقيعًا قائمًا على شجرة Merkle يسمح بالتحقق من الكتل الفردية أثناء تدفقها إلى الجهاز.

إذا فشل التحقق من التوقيع لأي سبب من الأسباب، فسيتم إحباط التثبيت على الفور. يمكنك التحقق من توقيع APK قبل التثبيت باستخدام أداة التحقق من APK.

تحديث مطابقة التوقيع

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

الخطوة 5: تأكيد المستخدم

بالنسبة لعمليات التثبيت التي تم تحميلها على الجانب، يعرض النظام مربع حوار تأكيد التثبيت الذي يوضح:

  • اسم التطبيق وأيقونته (مستخرج من موارد APK)
  • الأذونات التي يطلبها التطبيق (في إصدارات Android الأقدم)
  • سواء كان هذا تثبيتًا جديدًا أو تحديثًا
  • أي تحذيرات حول مصدر التطبيق أو المخاطر المحتملة

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

الخطوة 6: استخراج الملف ووضعه

بمجرد تأكيد المستخدم (أو لتثبيت متجر Play تلقائيًا)، يبدأ النظام في استخراج الملفات ووضعها:

تخزين APK

يتم نسخ ملف APK نفسه إلى /data/app/[package-name]-[random]/base.apk. بالنسبة لعمليات تثبيت APK المقسمة، يتم وضع ملفات إضافية مثل split_config.arm64_v8a.apk بجانب ملف APK الأساسي. لا يتم تعديل أو حذف ملف APK الأصلي الموجود في مجلد التنزيلات.

استخراج المكتبة الأصلية

إذا كان APK يحتوي على مكتبات أصلية (في دليل lib/، فسيتم استخراجها إلى /data/app/[package-name]-[random]/lib/[abi]/.) في إصدارات Android الأحدث، يمكن للتطبيقات اختيار الاحتفاظ بالمكتبات الأصلية مضغوطة داخل APK وتحميلها مباشرة باستخدام android:extractNativeLibs="false"، مما يوفر مساحة التخزين.

إنشاء دليل البيانات

يقوم النظام بإنشاء دليل البيانات الخاصة بالتطبيق على /data/data/[package-name]/ (أو /data/user/0/[package-name]/ على الأجهزة متعددة المستخدمين). هذا الدليل مملوك لمعرف Linux الفريد المخصص للتطبيق، مما يضمن عدم تمكن أي تطبيق آخر من الوصول إليه دون امتيازات الجذر.

الخطوة 7: تحسين DEX

هذه الخطوة هي حيث يقوم Android بتحويل الرمز الثانوي للتطبيق إلى تنسيق محسّن للأجهزة المحددة بالجهاز. لقد تطورت العملية بشكل ملحوظ عبر تاريخ Android:

عصر Dalvik (Android 4.4 والإصدارات الأقدم)

استخدم الجهاز الظاهري Dalvik الأصلي تجميع Just-In-Time (JIT). أثناء التثبيت، تم تحسين ملف classes.dex إلى ملف ODEX يحتوي على رمز بايت تم التحقق منه ومحسّن. كان هذا سريعًا نسبيًا ولكنه كان يعني أن التطبيق يعمل بشكل أبطأ في وقت التشغيل نظرًا لأن معظم التعليمات البرمجية لا تزال يتم تفسيرها.

ART مع AOT (Android 5.0 إلى 6.0)

حل Android Runtime (ART) محل Dalvik وقدم تجميعًا مسبقًا (AOT). أثناء التثبيت، تم تجميع كود DEX الثانوي بالكامل إلى كود الجهاز الأصلي. أدى هذا إلى تشغيل التطبيقات بشكل أسرع ولكنه أدى إلى زيادة كبيرة في وقت التثبيت واستخدام مساحة التخزين. استغرق تثبيت بعض التطبيقات عدة دقائق.

التجميع الموجه للملف الشخصي (Android 7.0+)

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

يتم تخزين التعليمات البرمجية المترجمة في /data/dalvik-cache/ أو بجانب APK كملفات .odex و.vdex و.art. يحتوي ملف .vdex على رمز DEX الذي تم التحقق منه، ويحتوي ملف .odex على تعليمات برمجية أصلية مجمعة، ويحتوي ملف .art على صور كومة الذاكرة المؤقتة التي تمت تهيئتها مسبقًا لبدء تشغيل أسرع.

الخطوة 8: تسجيل الإذن

تقوم PackageManagerService بتسجيل الأذونات والمكونات المعلنة للتطبيق في النظام:

  • يتم منح أذونات وقت التثبيت (مثل INTERNET أو VIBRATE تلقائيًا دون تدخل المستخدم).
  • تم تسجيل أذونات وقت التشغيل (مثل CAMERA أو LOCATION ولكن لم يتم منحه). يجب أن يطلبها التطبيق في وقت التشغيل.
  • يتم تسجيل مرشحات النية حتى يعرف النظام التطبيقات التي يمكنها التعامل مع الإجراءات (مثل فتح عنوان URL أو مشاركة المحتوى).
  • تم تسجيل مقدمي المحتوى لدى سلطاتهم حتى تتمكن التطبيقات الأخرى من الاستعلام عنهم.

الخطوة 9: تكامل النظام

تقوم الخطوات النهائية بدمج التطبيق في نظام Android:

  • تحديث قاعدة بيانات الحزمة: يتم تحديث قاعدة بيانات حزمة النظام (/data/system/packages.xml) بمعلومات التطبيق الجديد، بما في ذلك UID المخصص له والأذونات وإعلانات المكونات.
  • إشعار المشغل: يتم إخطار مشغل الشاشة الرئيسية بالتطبيق الجديد حتى يتمكن من عرض رمز التطبيق.
  • البث: يرسل النظام بث PACKAGE_ADDED، مما يسمح للتطبيقات الأخرى بالتفاعل مع التثبيت الجديد (على سبيل المثال، قد تقوم تطبيقات النسخ الاحتياطي بجدولة نسخة احتياطية).
  • سياق سيلينوكس: يتم تصنيف ملفات التطبيق بسياق أمان SELinux المناسب استنادًا إلى إصدار SDK المستهدف والأذونات المعلنة.

لماذا تفشل عمليات التثبيت

يساعد فهم مسار التثبيت في تشخيص حالات الفشل الشائعة:

  • "خطأ في التحليل": ملف APK تالف أو غير مكتمل أو يحتوي على بيان مشوه. يحدث هذا غالبًا مع التنزيلات غير المكتملة أو الملفات المحولة بشكل غير صحيح.
  • "التطبيق غير مثبت" (التوقيع غير متطابق): أنت تحاول تحديث تطبيق باستخدام APK موقع بمفتاح مختلف. يجب عليك إلغاء تثبيت الإصدار الموجود أولاً.
  • "مساحة التخزين غير كافية": لا توجد مساحة كافية لملف APK والمكتبات المستخرجة ومخرجات تحسين DEX. المساحة الفعلية المطلوبة هي عادةً 2-3 أضعاف حجم APK.
  • "تتعارض الحزمة مع الحزمة الموجودة": نفس اسم الحزمة ولكن التوقيع مختلف. شائع عند التبديل بين متجر Play والإصدارات المحملة جانبيًا.
  • تم حظر الرجوع إلى إصدار سابق: بشكل افتراضي، يمنع Android تثبيت إصدار أقدم على إصدار أحدث. يمكن لـ ADB تجاوز هذا باستخدام adb install -d.

تقسيم APK التثبيت

عند تثبيت ملفات APK المقسمة (من حزم التطبيقات)، تختلف العملية قليلاً. يستخدم النظام التثبيت على أساس الجلسة API:

  1. يتم إنشاء جلسة تثبيت جديدة
  2. تتم كتابة كل ملف APK منقسم إلى الجلسة
  3. تم الالتزام بالجلسة، مما أدى إلى تشغيل مسار التحقق الكامل
  4. يجب أن تحتوي جميع الانقسامات على أسماء حزم متطابقة ورموز الإصدار وشهادات التوقيع

هذه هي الآلية التي يستخدمها مثبتو XAPK وأدوات مثل APKS لدمج APK للتعامل مع عمليات التثبيت متعددة الملفات.

التثبيت عبر بنك التنمية الآسيوي

عند استخدام adb install، تتجاوز العملية المثبت الرسومي ولكنها تتبع نفس المسار الداخلي. يتواصل ADB مع خدمة مدير الحزم من خلال اتصال مأخذ التوصيل. وهو يدعم العلامات الإضافية غير المتوفرة من خلال واجهة المستخدم الرسومية:

  • -r: استبدال التطبيق الحالي (السماح بإعادة التثبيت)
  • -d: السماح بالرجوع إلى إصدار سابق
  • -g: منح كافة أذونات وقت التشغيل على الفور
  • -t: السماح بتثبيت ملفات APK للاختبار فقط
  • --install-multiple: تثبيت ملفات APK المقسمة في جلسة واحدة

ماذا يحدث أثناء إلغاء التثبيت

للاكتمال، إليك ما يحدث عند إزالة التطبيق:

  1. يتم قتل عمليات التطبيق
  2. يتم حذف ملف APK والمكتبات المستخرجة من /data/app/
  3. تتم إزالة دليل البيانات الخاصة بالتطبيق (ما لم يختر المستخدم الاحتفاظ بالبيانات)
  4. يتم حذف ملفات ذاكرة التخزين المؤقت DEX المترجمة
  5. يتم تحديث قاعدة بيانات الحزمة
  6. يتم إرسال بث PACKAGE_REMOVED
  7. يقوم المشغل بإزالة أيقونة التطبيق

لاحظ أن الملفات الخاصة بالتطبيقات الموجودة على وحدة التخزين الخارجية (/Android/data/[package]/ و/Android/obb/[package]/ يتم حذفها أيضًا على نظام التشغيل Android 10 والإصدارات الأحدث، وذلك بفضل فرض التخزين المحدد النطاق).

لماذا يؤدي فهم PackageManager إلى توفير وقت التصحيح

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

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

تم تصميمها وتوثيقها بواسطة Mst Shaefale المطور الرئيسي ومهندس حزم Android • تم التحقق منه على Android 12–15

يحتفظ Mst Shaefale بدمج XAPK/APKS من جانب العميل، ومحلل البيانات الثنائية، وأدوات توقيع APK v1+v2 في xapktoapk.com. اكتشاف أمر قديم أو تغيير نظام التشغيل؟ أرسل مذكرة تحريرية.