نظرة عامة على العمليات وسلاسل المحادثات

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

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

يناقش هذا المستند كيفية عمل العمليات وسلاسل المحادثات في تطبيق Android.

العمليات

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

يتيح إدخال البيان لكل نوع من عناصر المكوّنات، <activity> و<service> و<receiver> و<provider> استخدام السمة android:process التي يمكنها تحديد والعملية التي يعمل فيها المكون. يمكنك ضبط هذه السمة بحيث يتم تشغيل كل مكون في عمليته الخاصة أو بحيث تشترك بعض المكونات في عملية بينما لا تشترك الأخرى في ذلك.

يمكنك أيضًا تعيين android:process بحيث تعمل مكونات التطبيقات المختلفة معًا بشرط أن تشارك التطبيقات رقم تعريف مستخدم Linux نفسه وأن تكون مُوقعة باستخدام الشهادات نفسها.

<application> العنصر أيضًا السمة android:process، التي يمكنك استخدامها لضبط قيمة افتراضية تنطبق على جميع المكونات.

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

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

تتم مناقشة تفاصيل دورة حياة العملية وعلاقتها بحالات التقديم في مراحل نشاط التطبيقات والعمليات:

Threads

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

لا ينشئ النظام سلسلة محادثات منفصلة لكل مثيل من المكوِّن. الكل يتم إنشاء مثيل للمكونات التي تعمل في نفس العملية في مؤشر ترابط واجهة المستخدم، ويطلب النظام يتم نقل كل مكون من سلسلة التعليمات تلك. وبالتالي، فإن الطرق التي تستجيب للنظام عمليات معاودة الاتصال - مثل onKeyDown() للإبلاغ عن إجراءات المستخدم، أو طريقة معاودة الاتصال في مراحل النشاط، يتم تشغيلها دائمًا في سلسلة واجهة المستخدم ضمن العملية.

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

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

من منظور المستخدم، التطبيق معلق. والأسوأ من ذلك، إذا تم حظر مؤشر ترابط واجهة المستخدم لأكثر من بضع ثوانٍ، تظهر للمستخدم رسالة "التطبيق لا تستجيب" (ANR). قد يقرر المستخدم بعد ذلك إنهاء تطبيقك أو حتى إلغاء تثبيته بها.

يُرجى العِلم أنّ مجموعة أدوات واجهة المستخدم من Android ليست آمنة على سلاسل المحادثات. لذلك، لا تتعامل مع واجهة المستخدم من مؤشر ترابط العامل. إجراء جميع أشكال التلاعب بواجهة المستخدم من خلال واجهة المستخدم . هناك قاعدتان لنموذج سلسلة المحادثات الفردية في Android:

  1. لا تحظر سلسلة واجهة المستخدم.
  2. لا يمكن الوصول إلى مجموعة أدوات واجهة المستخدم من Android من خارج سلسلة واجهة المستخدم.

سلاسل المحادثات للعاملين

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

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

يستخدم المثال التالي السمة View.post(Runnable):

Kotlin

fun onClick(v: View) {
    Thread(Runnable {
        // A potentially time consuming task.
        val bitmap = processBitMap("image.png")
        imageView.post {
            imageView.setImageBitmap(bitmap)
        }
    }).start()
}

Java

public void onClick(View v) {
    new Thread(new Runnable() {
        public void run() {
            // A potentially time consuming task.
            final Bitmap bitmap =
                    processBitMap("image.png");
            imageView.post(new Runnable() {
                public void run() {
                    imageView.setImageBitmap(bitmap);
                }
            });
        }
    }).start();
}

يتوافق هذا التنفيذ مع سلسلة التعليمات لأنّه يتم تنفيذها في الخلفية من سلسلة محادثات منفصلة. بينما يتم التعامل مع ImageView دائمًا من سلسلة واجهة المستخدم.

ومع ذلك، ومع تزايد تعقيد العملية، يمكن أن يصبح هذا النوع من التعليمات البرمجية معقدًا يصعب صيانتها. للتعامل مع التفاعلات الأكثر تعقيدًا مع سلسلة العمال، قد تفكر استخدام Handler في سلسلة Worker لمعالجة الرسائل المرسلة من سلسلة واجهة المستخدم. للحصول على شرح كامل لكيفية وتحديد مواعيد العمل على سلاسل المحادثات في الخلفية والتواصل مرة أخرى مع سلسلة واجهة المستخدم، راجع نظرة عامة على العمل في الخلفية:

الطُرق الآمنة لسلاسل المحادثات

في بعض الحالات، يتم استدعاء الطرق التي تنفذها من أكثر من سلسلة محادثات، ومن ثمَّ يجب كتابتها لتكون آمنة لسلاسل المحادثات.

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

على سبيل المثال، في حين أن الخدمة يتم استدعاء طريقة onBind() من سلسلة واجهة المستخدم والطرق التي يتم تنفيذها في العنصر الذي يعرضه onBind()، مثل فئة فرعية تنفّذ طرق استدعاء الإجراء عن بُعد (RPC) يتم استدعاؤها من سلاسل المحادثات في حوض السباحة. ولأنّ الخدمة يمكن أن يكون لها أكثر من عميل، يمكن أن تتفاعل أكثر من سلسلة محادثات مجمّعة واحدة. استخدام طريقة IBinder نفسها في الوقت نفسه، وبالتالي يجب تنفيذ IBinder للحفاظ على أمان سلاسل المحادثات.

وبالمثل، يمكن لموفر المحتوى تلقي طلبات البيانات التي تنشأ في عمليات أخرى. ContentResolver وContentProvider على إخفاء تفاصيل كيفية إدارة الاتصال البيني للعمليات (IPC)، لكن الطرق ContentProvider التي تستجيب لهذه الطلبات - الطرق query(), insert(), delete(), update(), وgetType() — هي من مجموعة من سلاسل المحادثات ضمن عملية موفّر المحتوى، وليس من واجهة المستخدم سلسلة التعليمات الخاصة بهذه العملية. ولأن هذه الطرق قد يتم استدعاؤها من أي عدد من سلاسل المحادثات في في الوقت ذاته، يجب تنفيذها أيضًا لتكون آمنة لسلاسل المحادثات.

التواصل بين العمليات

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

تكون القيم المعروضة بعد ذلك ويتم نقلها في الاتجاه المعاكس. ويوفر Android جميع التعليمات البرمجية لإجراء عمليات IPC هذه لكي تتمكّن من التركيز على تحديد وتنفيذ واجهة برمجة RPC.

لإجراء IPC، يجب أن يرتبط تطبيقك بإحدى الخدمات التي تستخدم bindService(). لمزيد من المعلومات، يُرجى الاطّلاع على نظرة عامة على الخدمات.