مقدمة إلى أندرويد ومكوّنات المنصة
مقدمة إلى أندرويد ومكوّنات المنصة
أندرويد هو نظام التشغيل الأوسع انتشارًا في العالم. يعمل على الهواتف والأجهزة اللوحية والساعات الذكية والتلفزيونات والسيارات والأجهزة المدمجة. بوصفك مطوّرًا يعرف Java، أنت تمتلك بالفعل فهمًا راسخًا للتصميم الكائني التوجّه وآلة JVM والمكتبة القياسية. تبني هذه السلسلة التعليمية مباشرةً على ذلك الأساس لتعلّمك كتابة تطبيقات أندرويد حقيقية بلغة Java — وهي اللغة التي صُمّمت المنصة حولها منذ اليوم الأول.
قبل كتابة سطر واحد من الكود، من المفيد فهم ما هو أندرويد فعلًا، وكيف تتلاءم طبقاته معًا، وما الذي يميّزه جوهريًا عن برنامج Java سطحي. هذا الفهم هو ما يُفرّق بين مطوّر ينسخ النماذج الجاهزة ومطوّر يعرف لماذا توجد تلك النماذج.
مكدّس برمجيات أندرويد
أندرويد منصة ذات طبقات. كل طبقة تبني على التي تحتها، وبوصفك مطوّر تطبيقات تعمل أساسًا في الطبقة العليا — لكن الطبقات التحتية تشكّل كل شيء من الأداء إلى عمر البطارية إلى الأمان.
- نواة Linux — الأساس. تدير مشغّلات الأجهزة والذاكرة وجدولة العمليات وإدارة الطاقة والشبكات. لا تستدعيها مباشرةً أبدًا؛ فهي تعمل بصمت خلف كل استدعاء API.
- طبقة التجريد عن الأجهزة (HAL) — مجموعة واجهات قياسية تعزل مشغّلات النواة عن الطبقات الأعلى. تنفّذ الشركات المصنّعة هذه الواجهات حتى تبدو الكاميرا وجهاز GPS وبصمة الإصبع متماثلة لأندرويد بصرف النظر عن الرقاقة الكامنة.
- وقت تشغيل أندرويد (ART) — الآلة الافتراضية التي تشغّل تطبيقك. تُترجم ART كود Java (أو Kotlin) الثنائي إلى كود آلة أصلي باستخدام تجميع Ahead-Of-Time (AOT) أثناء تثبيت التطبيق، فيعمل كودك بسرعة شبه أصلية على الجهاز. حلّت ART محل وقت تشغيل Dalvik الأقدم منذ الإصدار أندرويد 5.0.
- مكتبات C/C++ الأصلية — قدرات المنصة الجوهرية كمسار رسومات OpenGL ES وقاعدة بيانات SQLite وWebKit وإطار الوسائط. تصل إليها بشكل غير مباشر عبر واجهات Java الأعلى مستوى، وإن كان Android NDK يتيح لك استدعاءها مباشرةً للكود ذي الأداء الحرج.
- إطار Java API — الطبقة التي تقضي معظم وقتك فيها. تعرض المنصة بأكملها عبر حزم Java منظّمة جيدًا:
android.appوandroid.viewوandroid.contentوandroid.osوغيرها الكثير. كل Activity وService وإشعار ومستشعر واتصال شبكي يُصل إليه عبر هذه الطبقة. - تطبيقات النظام وتطبيقك — الطبقة العليا. تطبيقات الاتصال وجهات الاتصال والكاميرا والإعدادات المُثبّتة مسبقًا تعيش هنا — وكذلك كل تطبيق تثبّته، بما في ذلك تطبيقك. جميعها مواطنون متساوون يعملون في نفس الإطار.
كيف تتركّب تطبيقات أندرويد
تطبيق أندرويد ليس ملفًا تنفيذيًا واحدًا. إنه حزمة — ملف .apk (Android Package) أو .aab (Android App Bundle) — يحتوي على كود مُجمَّع وموارد (تخطيطات وسلاسل نصية وصور) وأصول وملف manifest يصف الحزمة لنظام التشغيل.
داخل التطبيق قيد التشغيل، تنظّم المنصة الكود حول أربعة لبنات بناء أساسية:
- Activity — شاشة واحدة بواجهة مستخدم. كل شاشة يراها المستخدم تقابل فئة فرعية من Activity. تنشئ المنصة نسخ Activity وتُدمّرها وفق دورة حياة محدّدة بدقة ستتعلّمها بعمق في درس لاحق.
- Service — مكوّن يؤدي عملًا طويل الأمد في الخلفية دون واجهة مستخدم. أمثلة: تشغيل الموسيقى، ومزامنة البيانات، ومعالجة طلبات الشبكة. تعمل Services على الخيط الرئيسي افتراضيًا وعليها تفويض العمليات الحاجبة إلى خيوط خلفية.
- BroadcastReceiver — مستمع لأحداث على مستوى النظام أو التطبيق. يبثّ النظام أحداثًا مثل "البطارية منخفضة" و"الشبكة متصلة" و"اكتمل التشغيل"؛ يتفاعل مستقبلك معها. لا تملك المستقبلات واجهة مستخدم ومن المتوقع أن تنتهي بسرعة.
- ContentProvider — واجهة منظّمة لمشاركة البيانات بين التطبيقات. تُعرَض قواعد بيانات جهات الاتصال وMediaStore كـ ContentProviders، ما يتيح لتطبيقك استعلامها عبر واجهة مبنية على URI دون معرفة تنسيق تخزينها الداخلي.
معظم التطبيقات التي ستكتبها في البداية ستتكوّن تقريبًا بالكامل من Activities، فيما تظهر Services وBroadcastReceivers مع نمو التطبيق في التعقيد.
دور AndroidManifest
يجب الإعلان عن كل مكوّن — كل Activity وService وBroadcastReceiver وContentProvider — في AndroidManifest.xml قبل أن يشغّله أندرويد. يُعلن المانيفست أيضًا عن الأذونات التي يحتاجها التطبيق، ومستويات API الأدنى والمستهدف، وميزات الأجهزة التي يعتمد عليها، وActivity نقطة الدخول التي يفتحها أيقونة المشغّل. ستدرس المانيفست بالتفصيل في الدرس السادس؛ في الوقت الراهن، تذكّر أن أندرويد سيرفض بصمت تشغيل أي مكوّن غير مسجّل فيه.
AndroidManifest.xml. سيُجمَّع التطبيق بنجاح، لكن محاولة التنقل إلى تلك الشاشة وقت التشغيل تُلقي استثناء ActivityNotFoundException. يستطيع Android Studio إضافة الإدخال تلقائيًا عند استخدام معالج "New Activity" — استخدمه لتجنب ذلك.
العزل الأمني (Sandboxing)
يطبّق أندرويد عزلًا صارمًا بين التطبيقات على مستوى نظام التشغيل. يعمل كل تطبيق في عملية Linux خاصة به بمعرّف مستخدم فريد (UID). مجلدات نظام الملفات الخاصة بتطبيق واحد غير قابلة للوصول من تطبيق آخر. حتى النظام لا يستطيع قراءة الملفات الخاصة بتطبيقك دون الإعلان عن ContentProvider.
الأذونات هي الآلية الرسمية للتجاوز عبر حدود العزل. التطبيق الذي يحتاج قراءة جهات اتصال المستخدم يجب أن يُعلن uses-permission android:name="android.permission.READ_CONTACTS" في مانيفسته. منذ أندرويد 6.0 (API 23) وما فوق، يجب أيضًا طلب الأذونات الحساسة وقت التشغيل — يرى المستخدم مربع حوار ويمكنه منح كل إذن أو رفضه بشكل مستقل.
مستويات API والإصدارات
تُعرَّف إصدارات أندرويد بشيئين: اسم (مثل Android 14) وعدد صحيح يُسمّى مستوى API (مثل API 34). مستويات API هي ما تعمل به في الكود. في build.gradle تُحدد:
minSdk— أقدم إصدار أندرويد يدعمه تطبيقك. لا يستطيع المستخدمون على الأجهزة الأقدم تثبيته.targetSdk— مستوى API الذي صُمّم تطبيقك واختُبر مقابله. يطبّق النظام سلوكيات التوافق مع الإصدارات السابقة لأي مستوى API أعلى من هدفك.compileSdk— نسخة Android SDK المستخدمة لتجميع كودك. اضبطها على أحدث مستوى API مستقر.
حين تستدعي API مقدَّمة في مستوى أعلى من minSdk، يُصدر المُجمِّع تحذير lint. يجب حماية هذا الاستدعاء بفحص الإصدار:
ما يُميّز أندرويد عن Java السطحية
إن كنت قد كتبت تطبيقات Swing أو JavaFX فأنت معتاد على وجود طريقة main() كنقطة دخول واستمرار العملية طالما نافذتك مفتوحة. يعمل أندرويد بشكل مختلف في عدة جوانب جوهرية:
- لا طريقة
main(). يستدعي إطار أندرويد طرق دورة الحياة على مكوّناتك. تستجيب لنداءات الاسترجاع (callbacks) مثلonCreate()وonStart()وonResume()— لا تكتب أبدًا حلقة تُبقي العملية حيّة. - النظام يمتلك العملية. يمكن لأندرويد إنهاء عملية تطبيقك في أي وقت لاسترداد الذاكرة — خاصةً حين يكون التطبيق في الخلفية. يجب حفظ الحالة قبل أن تُنهى واستعادتها حين تعود.
- خيط واحد لواجهة المستخدم. يجب أن تحدث جميع تحديثات واجهة المستخدم على الخيط الرئيسي (يُسمّى أيضًا خيط الواجهة). أي عملية حاجبة — استدعاءات شبكة، أو I/O ملفات، أو استعلامات قواعد بيانات — يجب تنفيذها على خيط خلفي. حجب الخيط الرئيسي لأكثر من ~5 ثوانٍ يُطلق مربع حوار ANR (Application Not Responding).
- بيئة محدودة الموارد. حتى الهواتف الحديثة تملك ذاكرة RAM وموارد CPU أقل بكثير من سطح المكتب. تسريبات الذاكرة والتخصيصات غير الضرورية والعمليات المكلفة على الخيط الرئيسي لها عواقب فورية يراها المستخدم.
الخلاصة
أندرويد منصة ذات طبقات مبنية على نواة Linux، حيث تنفّذ ART كود Java كأكواد آلة أصلية مُجمَّعة. التطبيقات حزم تتكوّن من أربعة أنواع من المكوّنات — Activity وService وBroadcastReceiver وContentProvider — يُعلَن عن كل منها في AndroidManifest.xml. تطبّق المنصة العزل على مستوى العملية ونظام أذونات وقاعدة صارمة بأن عمل واجهة المستخدم يجب أن يبقى على الخيط الرئيسي. هذه القيود موجودة للحفاظ على استجابة التطبيقات وأمانها وكفاءتها في استهلاك الطاقة على الأجهزة التي يحملها الناس فعلًا. في الدرس القادم ستثبّت Android Studio وتنشئ مشروعك الأول وترى هذه البنية في شجرة ملفات حقيقية.