في مقالة سابقه بعنوان طبقات الهيكلة الهندسية في الاندرويد تعرفنا على العمليات التي بداخلها يعيش تطبيقنا وتعيش الخيوط الحاسوبية كذلك. في هذه المقالة سنتعرف اكثر على الخيوط الحاسوبية ووظائفها ومكوناتها.

عملية نرى بداخلها تطبيق وبداخل ذلك التطبيق خيطين حاسوبيين. الاخضر والاحمر.

الشبكة الرقمية, اقصى ما انتهى اليه العلم في المجال الرقمي. حاولت تخيل مجموعات من المعلومات اثناء انتقالها في الاجهزة الحاسوبية. كيف هي اشكالهم؟ كالسفن والدراجات الناريه؟ وهل الدوائر الكهربائية مثل الطرق السريعه؟ ظللت احلم بذلك العالم, اعتقدت انني لن اراه ابداً. وفي يوم من الايام, اقحمت نفسي بداخله!
Kevin Flynn in movie: Tron Legacy

الخيط الحاسوبي

نستطيع القول بان الخيط الحاسوبي (Thread) هو حلقة الوصل بين تطبيقك (المهام التي يحتويها, اي بين اسطرك البرمجيه) ووحدة المعالجة المركزية CPU للهاتف. فبدون خيط حاسوبي لاتستطيع تشغل اي سطر برمجي في تطبيقك, لذلك عندما تقوم بتشغيل تطبيقك يقوم نظام الاندرويد بأنشاء خيط حاسوبي مجاناً يسمى بالخيط الرئيسي, كالصورة التالي:

حاول الربط بين الصورة الاولى وهذه الصوره تخيل الان انك تنظر من الاعلى الى الاسفل

الخيط الحاسوبي الرئيسي 

عند تشغيل اي تطبيق في نظام الاندرويد فانه يعمل له خيط حاسوبي واحد ويسمى هذا الخيط بالتسميات Main Thread و UI Thread. يعتبر هذا الخيط مهم جداً ويجب الا يكثر استخدامه المبرمج لإجراء عملياته وحشر اسطره البرمجية.

وظيفة الخيط الحاسوبي الرئيسي

  • هو المسؤل عن رسم وعرض العناصر الى المستخدم في الشاشة.
  • هو المسؤل عن رصد الاحداث التي يحدثها المستخدم للتطبيق (مثلاً قيام المستخدم بالنقر على عنصر Button).

ماذا يحدث لو اكثرنا استخدام الخيط الحاسوبي الرئيسي

من المعروف ان جميع شفراتك البرمجية يتم نقلها الى المعالج من خلال هذا الخيط. مثلاً تعاملك مع قواعد البيانات (كالـ SQLite او Room), استقبال وارسال البيانات الى الشبكة العنكبوتية, وما الى ذلك. اذا اكثرت المهام على هذا الخيط سيكون تطبيقك بطئ جداً وفي اغلب الاحيان سيتوقف عن العمل لمدة معينة من الوقت. التوقف لمدة خمس ثواني سيسبب للمستخدم ظهور هذة المشكلة:
application not responding” (ANR) dialog
وهذا سيدعو المستخدم الى اغلاق تطبيقك وحذفه من جهازه.

نقاط مهمة للتعامل مع الخيط الحاسوبي الرئيسي

وعلى ذلك نستطيع تحديد اهم نقطتان عند التعامل مع الخيط الحاسوبي الرئيسي وهما:

  1. لاتقم بحجز هذا الخيط, وذلك من خلال اجراء بعض العمليات الطويلة او التي تتطلب جهد. كالاستعلام عن الالف الحقول في قاعدة البيانات او التعامل مع الشبكة العنكبوتية  عليه كالـ الخوادم  والـ API.
  2. لاتقم بمحاولة استخدام اي من عناصر الواجهه خارج هذا الخط. مثلاً تريد تحديث نص لعنصر TextView من خارج هذا الخيط كتحديثها من خلال خيوط اخرى (Background Threads) فهذا سيسبب تعطل تطبيقك.

ما الحل؟

هو انشاء خيط حاسوبي اخر لمهامك الثقيله. وهكذا يصبح لديك خطين حاسوبيين بداخل الـ Process الخاصة بتطبيقك, كالصورة التالية:

اشياء يجب عليك تذكرها

وتذكر ان الخيط الحاسوبي الرئيسي يطلق عليه المصطلحات التالية:

  • الـ Main Thread.
  • الـ UI Thread.

والخيوط الاخرى التي تنشئها تستطيع تسميتها كما تريد ولكن يطلق عليها بالمصطلحات التالية:

  • الـ Background Thread.
  • الـ Worker Thread.

مكونات الخيوط الحاسوبية في نظام الاندرويد

لنفرض ان لدينا جهاز هاتف اندرويد ذو معالجين, ويدعم تعدد الانويه. كما بالصورة التالية:

الان لإجراء اي عملية في التطبيق نحتاج لربطه بالمعالج اليس كذلك؟ ولهذا نحتاج الى انشاء خيط حاسوبي. ومن حسن الحظ ان نظام الاندرويد ينشئ لنا خط حاسوبي افتراضي ويسمى Main Thread و UI Thread كما هو موضح بالشكل الاعلى.

مكونات الخيوط الحاسوبي (Threads)

والان لفهم الخيط الحاسوبي بشكل دقيق, نحتاج الى فهم مكوناته وهي كالتالي:

  • الـ Runnable.
  • الـ Callable.
  • الـ Future Object.
  • الـ Message.
  • الـ Handler.
  • الـ Message Queue.
  • الـ Looper.

الـ Runnable

عبارة عن واجهه Interface من خلالها نقوم بتغليف الشفرة التي نريد ارسالها على الخيط للمعالج. وتحتوي هذة الواجهة على دالة واحدة وهي run() نضع بداخلها الشفرة المراد تغليفها. ثم نقوم بارسال هذا الـ Runnable على الخيط الحاسوبي باستخدام Handler.

الـ Runnable عبارة عن كائن يغلف الشفرة البرمجية لإرسالها الى المعالج.

الـ Callable

الـ Callable مشابه للـ Runnable ولكن الفرق هو انه يستطيع ارجاع قيمة ما (بعكس الـ Runnable لايستطيع ارجاع اي قيمه) وتغلف تلك القيمة في عنصر مستقبلي.

الـ Future عنصر مستقبلي للبيانات

 تغلف القيمة التي يقوم الـ Callable بإرجاعها في عنصر من هذا نوع Future.

الـ Message

اي شئ ينقل الى الخيط الحاسوبي نستطيع تسميته بالـ Message (تستطيع فهمها على انها طبقه اخرى من الـ Abstraction بين الخيط الحاسوبي و كل ماتريد وضعه عليه). اي اننا نستطيع ان نضع بيانات بداخل Message ثم ارسالها الى الخيط الحاسوبي, ونستطيع كذلك وضع Runnable في الـ Message ثم نقلها الى الخيط الحاسوبي.

الـ Handler

لكل خيط حاسوبي يوجد Handler خاص به. ومن خلال الـ Handler نستطيع وضع الـ Runnable او ما يسمى بالـ Message على الخيط الحاسوبي (Thread) وذلك بوضعه بداخل الـ Message Queue. وايضاً الـ Handler يمكننا من نقل الـ Message من خيط حاسوبي الى اخر (نقل البيانات من الخيط الحاسوبي الخلفي الى الخيط الحاسوبي الرئيسي).

اي ان وظائف الـ Handler هي:

  • وضع البيانات على الخيط الحاسوبي.
  • ينقل البيانات بين الخيوط الحاسوبيه المختلفه (حلقة وصل بين الخيوط).

الـ Message Queue

اذا تم استلام عناصر Messages او Runnable من الـ Handler يأتي دور هذه الكلاس حيث يتضح من اسمها عملها Message Queue اي انها فقط تقوم بعمل List لهذه العناصر المستلمه والتي تحتوي على اسطرنا البرمجية لترتيب تشغيلها.

الـ Looper

عبارة عن كلاس مخصصة تقوم وظيفتها على تحريك و تشغيل الـ Runnable او Message في الخيط الحاسوبي (Thread) وابقائه نشط (تحريك الـ Message Queue). وايضاً من خلالها نستطيع جدولة الوقت لتشغيل الـ Runnalbe او Message اذا اردنا ذلك.

في المقالات القادمة باستخدام هذه الكائنات والكلاسات والواجهات سنقوم بعمل العديد من الانماط لتشغيل المهام على خيوط حاسوبية خلفيه (Worker Thread, Background Thread) مختلفه عن الخيط الرئيسي (Main Thread, UI Thread).

لاتقلق فبالتأكيد انك قمت باستخدام بعض من هذة الانماط امثال الـ AsyncTask و Loader وربما اخرى كـ Thread Pools وهو مايسمى بالـ Executor.


0 Comments

اترك رد