Activity — مكون أساسي لتطبيق Android يمثل شاشة واحدة بواجهة مستخدم. يدير النظام الشاشات من خلال دورة حياة صارمة — استدعاءات onCreate وonResume وonDestroy. يتم الإعلان عن كل Activity في AndroidManifest.xml ويتم تشغيلها عبر Intent. اقرأ المزيد عن تاريخ Android في وثائق Google الرسمية.
الملامح الرئيسية
Activity — مكون رئيسي لتطبيق Android يوفر نافذة للتفاعل مع المستخدم. يدير كل Activity شاشة منفصلة: قائمة المهام، نموذج تسجيل الدخول، عارض الصور. يقوم نظام Android بإنشاء Activity عند الطلب ويدمرها عندما تحتاج التطبيقات الأخرى إلى الذاكرة.
ظهر Activity لأول مرة في Android 1.0 (2008) ولا يزال اللبنة الأساسية للواجهة. وفقًا لـ Google (2026)، 98% من التطبيقات في Google Play تحتوي على Activity واحد على الأقل. في الهندسة المعمارية الحديثة، توصي Google باستخدام Activity واحد مع Fragments متعددة، ومع ذلك تظل التطبيقات متعددة الشاشات الكلاسيكية ممارسة شائعة.
Activity stack (back stack) — كومة المهام التي تخزن تاريخ التنقل. عندما يضغط المستخدم على "رجوع"، يتم تدمير Activity الحالي واستعادة السابق. يدير النظام الكومة تلقائيًا، ولكن يمكن للمطور التحكم في السلوك من خلال launchMode وعلامات Intent.
دورة حياة Activity هي مجموعة من الحالات والاستدعاءات التي تمر بها الشاشة من الإنشاء إلى التدمير. فهم Lifecycle أمر بالغ الأهمية: التعامل غير الصحيح مع الحالات يؤدي إلى تسرب الذاكرة وفقدان البيانات وتعطل التطبيق.
يستدعي نظام Android الاستدعاءات بترتيب صارم. يقوم المطور بتجاوز الطرق اللازمة لتهيئة الموارد وحفظ البيانات وتحرير الذاكرة. كل استدعاء له زوج مقابل: onCreate ↔ onDestroy، onStart ↔ onStop، onResume ↔ onPause.
| الاستدعاء | الغرض | إجراء المطور |
|---|---|---|
| onCreate | يُستدعى عند إنشاء Activity | تهيئة واجهة المستخدم، الاشتراك في ViewModel |
| onStart | يصبح Activity مرئيًا | بدء الرسوم المتحركة والكاميرا ونظام تحديد المواقع |
| onResume | يحصل Activity على تركيز الإدخال | استئناف الفيديو والمؤقتات |
| onPause | يفقد Activity التركيز | حفظ المسودات وإيقاف الرسوم المتحركة |
| onStop | يكون Activity مخفيًا بواسطة شاشة أخرى | تحرير الموارد الثقيلة |
| onDestroy | يتم تدمير Activity | تنظيف الاشتراكات و Closeable |
هناك أربع حالات لـ Activity: Running (onResume نشط)، Paused (مرئي ولكن بدون تركيز)، Stopped (غير مرئي)، Destroyed (مدمر). يمكن للنظام قتل Activity في حالة Stopped عند نقص الذاكرة — يجب حفظ البيانات في onSaveInstanceState.
دعنا نلقي نظرة على ثلاث طرق رئيسية لدورة حياة Activity مع مثال بلغة Kotlin. onCreate — نقطة الدخول، تُستدعى مرة واحدة. هنا يحدث ربط التخطيط عبر setContentView وتهيئة RecyclerView والاشتراك في LiveData. onStart — يصبح Activity مرئيًا للمستخدم. onResume — يحصل Activity على التركيز ويكون جاهزًا للتفاعل.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val recyclerView = findViewById<RecyclerView>(R.id.rv_items)
recyclerView.layoutManager = LinearLayoutManager(this)
loadItems()
}
override fun onStart() {
super.onStart()
startLocationUpdates()
}
override fun onResume() {
super.onResume()
resumeVideoPlayer()
}
}في المثال، يقوم onCreate بتهيئة RecyclerView وتحميل البيانات. يقوم onStart بتشغيل تحديثات الموقع الجغرافي — وهو مورد يجب أن يعمل فقط عندما تكون الشاشة مرئية. يستأنف onResume الفيديو الذي تم إيقافه في onPause. هذا الفصل يمنع العمل غير الضروري في الخلفية.
يجب الإعلان عن كل Activity في ملف AndroidManifest.xml. بدون تسجيل، لن يعثر النظام على الشاشة وسيطرح استثناء ActivityNotFoundException. يحدد البيان اسم الفئة والموضوع والاتجاه و launchMode ومرشحات Intent.
<application
android:allowBackup="true"
android:label="@string/app_name"
android:theme="@style/Theme.MyApp">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".DetailActivity"
android:parentActivityName=".MainActivity" />
</application>يحدد العلم exported ما إذا كانت التطبيقات الأخرى يمكنها تشغيل Activity. للشاشة الرئيسية exported=true، للشاشات الداخلية — false. السمة parentActivityName تمكن التنقل القياسي "لأعلى" (Up Navigation).
Intent — كائن يصف الإجراء الذي يجب تنفيذه. في سياق Activity، يُستخدم Intent لتشغيل شاشة أخرى مع نقل البيانات. يمكن أن يكون Intent صريحًا (يحدد فئة معينة) ضمنيًا (يحدد إجراءً، ويختار النظام المكون المناسب).
// Intent صريح — تشغيل DetailActivity مع البيانات
val intent = Intent(this, DetailActivity::class.java).apply {
putExtra("item_id", itemId)
putExtra("item_name", itemName)
}
startActivity(intent)
// الحصول على البيانات في DetailActivity
val itemId = intent.getLongExtra("item_id", 0L)
val itemName = intent.getStringExtra("item_name") ?: ""للحصول على نتيجة من Activity تم تشغيله، يُستخدم Activity Result API، الذي حل محل startActivityForResult القديم. واجهة برمجة التطبيقات الجديدة آمنة من حيث الكتابة وتصريحية وتعمل مع Jetpack Compose.
private val getResult = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
if (result.resultCode == Activity.RESULT_OK) {
val data = result.data?.getStringExtra("result_key")
}
}
fun openPicker() {
val intent = Intent(this, PickerActivity::class.java)
getResult.launch(intent)
}عند تدوير الشاشة أو تغيير التكوين، يعيد Android إنشاء Activity — يستدعي onDestroy و onCreate بالتسلسل. بدون حفظ الحالة، يفقد المستخدم البيانات المدخلة وموضع التمرير والعناصر المحددة. يوفر Android آليتين لحل هذه المشكلة: onSaveInstanceState و ViewModel.
يحفظ onSaveInstanceState البيانات البسيطة في Bundle قبل استدعاء onDestroy. يتحمل ViewModel من Jetpack إعادة إنشاء Activity ويخزن البيانات في الذاكرة، وهو أكثر كفاءة للكائنات المعقدة وطلبات الشبكة.
class MainActivity : AppCompatActivity() {
private val viewModel: MainViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// ViewModel يحفظ البيانات تلقائيًا
viewModel.items.observe(this) { items ->
updateAdapter(items)
}
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putInt("scroll_position", recyclerView.computeVerticalScrollOffset())
}
}نهج Google الحديث هو هندسة Single Activity مع Activity واحد وFragments متعددة. يستخدم التطبيق MainActivity واحد، ويتم التعامل مع جميع التنقلات بواسطة Navigation Component عبر NavHostFragment. المزايا: تنقل مركزي، ViewModel مشترك لكل شاشة، معالجة صحيحة للروابط العميقة (Deep Links).
يقوم Jetpack Navigation Component بأتمتة إدارة back stack ورسوم الانتقال وتمرير الوسائط. يتم وضع NavHostFragment في تخطيط Activity، ويصف رسم التنقل (NavGraph) جميع الشاشات والاتصالات بينها. يوصى بهذا النهج من قبل Google للمشاريع الجديدة ويتوافق مع مبادئ Material Design.
class MainActivity : AppCompatActivity() {
private val navController by lazy {
findViewById<NavHostFragment>(R.id.nav_host_fragment)
.navController
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// إعداد NavigationUI لـ AppBar
setupActionBarWithNavController(navController)
}
override fun onSupportNavigateUp() =
navController.navigateUp() || super.onSupportNavigateUp()
}الأسئلة الشائعة
Activity — شاشة تطبيق كاملة بدورة حياة خاصة بها. Fragment — جزء من واجهة المستخدم داخل Activity يتحمل إعادة إنشاء Activity ويعتمد على دورة حياته. Activity إلزامي، Fragment اختياري.
لا توجد حدود. كل شاشة تمثل عادة Activity منفصلاً. لتطبيق بسيط يكفي واحد، للتطبيقات متعددة الشاشات — من 5 إلى 20. توصي Google باستخدام Activity واحد مع Fragments متعددة.
launchMode يحدد كيفية إنشاء Activity في كومة المهام. أربعة أوضاع: standard (يتم إنشاء مثيل جديد)، singleTop، singleTask (مثيل واحد لكل مهمة) و singleInstance (مهمة معزولة). يتم تعيين الوضع في AndroidManifest.xml.
عبر Intent — كائن مع extras (putExtra) يمكن أن يحتوي على أنواع بدائية وسلاسل و Parcelable أو Serializable. للاتصال العكسي، يُستخدم Activity Result API — بديل حديث وآمن من حيث الكتابة لـ startActivityForResult.
Configuration Change — إعادة إنشاء Activity عند تغيير التكوين (تدوير الشاشة، تغيير اللغة، لوحة المفاتيح). يستدعي النظام onDestroy → onCreate. لحفظ البيانات، استخدم onSaveInstanceState أو ViewModel من Jetpack.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.