مراحل النشاط

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

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

تتيح لك كل معاودة اتصال تنفيذ عمل معين المناسبة لتغيير معين في الحالة. القيام بالعمل الصحيح على اليمين في الوقت المناسب والتعامل مع الانتقالات بشكل صحيح، تصبح تطبيقك أكثر قوة وأداءً أفضل. على سبيل المثال، يمكن أن يساعد التنفيذ الجيد لاستدعاءات مراحل النشاط في تطبيقك تجنَّب ما يلي:

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

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

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

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

مفاهيم دورة حياة النشاط

للتنقل بين الانتقالات بين مراحل دورة حياة النشاط، توفّر الفئة Activity مجموعة أساسية من ست استدعاءات: onCreate(), onStart(), onResume(), onPause(), onStop() و onDestroy() يستدعي النظام كل من عمليات الاستدعاء هذه عند دخول النشاط حالة جديدة.

يقدم الشكل 1 تمثيلاً مرئيًا لهذا النموذج.

الشكل 1. صورة صورة توضيحية لدورة حياة النشاط.

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

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

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

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

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

يقدم هذا القسم معلومات مفهومة ومعلومات التنفيذ حول طرق معاودة الاتصال المستخدمة أثناء دورة حياة النشاط.

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

onCreate()

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

على سبيل المثال، قد يؤدي تنفيذ onCreate() إلى ربط البيانات بالقوائم، وربط النشاط ViewModel, وإنشاء مثيل لبعض متغيرات نطاق الفئة. تتلقى هذه الطريقة مَعلمة savedInstanceState، وهي قيمة Bundle يحتوي على الحالة المحفوظة سابقًا للنشاط. إذا كان النشاط يتضمن لم يكن موجودًا من قبل، فإن قيمة الكائن Bundle فارغة.

إذا كان لديك مكون خاضع لدورة الحياة مرتبط بدورة حياة نشاطك، فسيتلقّى ON_CREATE فعالية. تُعرف الطريقة التي تتم إضافة تعليقات توضيحية إليها باستخدام @OnLifecycleEvent باسم الطريقة التي تكون على دراية بها خلال مراحل النشاط تنفيذ أي رمز إعداد يحتاج إليه في حالة الإنشاء.

المثال التالي لطريقة onCreate() تعرض عملية الإعداد الأساسية للنشاط، مثل الإعلان عن واجهة المستخدم (معرَّفة في ملف تنسيق XML)، وتحديد متغيرات العضو، وضبط بعض واجهة المستخدم. في هذا المثال، يجتاز ملف تنسيق XML معرّف مورد الملف R.layout.main_activity إلى setContentView()

Kotlin

lateinit var textView: TextView

// Some transient state for the activity instance.
var gameState: String? = null

override fun onCreate(savedInstanceState: Bundle?) {
    // Call the superclass onCreate to complete the creation of
    // the activity, like the view hierarchy.
    super.onCreate(savedInstanceState)

    // Recover the instance state.
    gameState = savedInstanceState?.getString(GAME_STATE_KEY)

    // Set the user interface layout for this activity.
    // The layout is defined in the project res/layout/main_activity.xml file.
    setContentView(R.layout.main_activity)

    // Initialize member TextView so it is available later.
    textView = findViewById(R.id.text_view)
}

// This callback is called only when there is a saved instance previously saved using
// onSaveInstanceState(). Some state is restored in onCreate(). Other state can optionally
// be restored here, possibly usable after onStart() has completed.
// The savedInstanceState Bundle is same as the one used in onCreate().
override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
    textView.text = savedInstanceState?.getString(TEXT_VIEW_KEY)
}

// Invoked when the activity might be temporarily destroyed; save the instance state here.
override fun onSaveInstanceState(outState: Bundle?) {
    outState?.run {
        putString(GAME_STATE_KEY, gameState)
        putString(TEXT_VIEW_KEY, textView.text.toString())
    }
    // Call superclass to save any view hierarchy.
    super.onSaveInstanceState(outState)
}

Java

TextView textView;

// Some transient state for the activity instance.
String gameState;

@Override
public void onCreate(Bundle savedInstanceState) {
    // Call the superclass onCreate to complete the creation of
    // the activity, like the view hierarchy.
    super.onCreate(savedInstanceState);

    // Recover the instance state.
    if (savedInstanceState != null) {
        gameState = savedInstanceState.getString(GAME_STATE_KEY);
    }

    // Set the user interface layout for this activity.
    // The layout is defined in the project res/layout/main_activity.xml file.
    setContentView(R.layout.main_activity);

    // Initialize member TextView so it is available later.
    textView = (TextView) findViewById(R.id.text_view);
}

// This callback is called only when there is a saved instance previously saved using
// onSaveInstanceState(). Some state is restored in onCreate(). Other state can optionally
// be restored here, possibly usable after onStart() has completed.
// The savedInstanceState Bundle is same as the one used in onCreate().
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
    textView.setText(savedInstanceState.getString(TEXT_VIEW_KEY));
}

// Invoked when the activity might be temporarily destroyed; save the instance state here.
@Override
public void onSaveInstanceState(Bundle outState) {
    outState.putString(GAME_STATE_KEY, gameState);
    outState.putString(TEXT_VIEW_KEY, textView.getText());

    // Call superclass to save any view hierarchy.
    super.onSaveInstanceState(outState);
}

كبديل لتحديد ملف XML وإرساله إلى setContentView()، عليك يمكنك إنشاء عناصر View جديدة في رمز النشاط العرض الهرمي من خلال إدراج كائنات View جديدة في ViewGroup يمكنك بعد ذلك استخدام هذا التخطيط عن طريق تمرير جذر ViewGroup إلى setContentView(). لمزيد من المعلومات عن إنشاء واجهة مستخدم، يمكنك الاطّلاع على واجهة المستخدم.

لن يظل نشاطك في قسم الولاية. بعد انتهاء طريقة onCreate() من التنفيذ، يدخل النشاط في الحقل Started (تم البدء). ويطلب النظام onStart() وonResume() طريقة في وتعاقب.

onStart()

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

عندما ينتقل النشاط إلى حالة "تم البدء"، يتم ربط أي مكوّن خاضع لمراحل النشاط إلى دورة حياة النشاط حدث ON_START.

يتم إكمال الطريقة onStart() بسرعة، وكما هو الحال مع حالة الإنشاء، لا يظل النشاط في حالة البدء. بعد انتهاء معاودة الاتصال هذه، يدخل النشاط تم الاستئناف ويستدعي النظام طريقة onResume()

onResume()

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

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

وعند وقوع حدث مقاطعة، يدخل النشاط في الوضع متوقف مؤقتًا. ويستدعي النظام معاودة الاتصال onPause().

إذا عاد النشاط إلى حالة الاستئناف من حالة الإيقاف المؤقت، يستدعي النظام مرة أخرى طريقة onResume(). لهذا السبب، نفِّذ onResume() لإعداد المكونات التي تصدر خلالها onPause() وتنفيذ أي مهام أخرى التي يجب أن تحدث في كل مرة يدخل فيها النشاط إلى العمود الولاية.

في ما يلي مثال على مكون خاضع لمراحل النشاط يمكنه الوصول إلى الكاميرا عند يتلقى المكوِّن حدث ON_RESUME:

Kotlin

class CameraComponent : LifecycleObserver {
    ...
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun initializeCamera() {
        if (camera == null) {
            getCamera()
        }
    }
    ...
}

Java

public class CameraComponent implements LifecycleObserver {

    ...

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    public void initializeCamera() {
        if (camera == null) {
            getCamera();
        }
    }
    ...
}

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

إذا كنت يريدون أن تكون الكاميرا نشطة عند استئناف التطبيق فقط (مرئية) وتفعيلها في المقدّمة)، ثم إعداد الكاميرا بعد حدث واحد (ON_RESUME) كما هو موضح سابقًا. إذا أردت إبقاء الكاميرا نشطة أثناء ممارسة النشاط متوقفة مؤقتًا ولكنها مرئية، كما هو الحال في وضع النوافذ المتعددة، إعداد الكاميرا بعد حدث ON_START.

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

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

بغض النظر عن حدث الإنشاء الذي تختاره تأكد من استخدام دورة الحياة المقابلة لتحرير المورد. إذا قمت بتهيئة شيء ما بعد حدث "ON_START"، أو إصداره أو إنهاؤه بعد حدث ON_STOP. إذا كنت بعد حدث ON_RESUME، ثم يتم تحريره بعد حدث ON_PAUSE.

يضع مقتطف الرمز السابق رمز إعداد الكاميرا في حساس لمراحل النشاط. يمكنك بدلاً من ذلك وضع هذا الرمز مباشرةً في النشاط. عمليات الاستدعاء في مراحل النشاط، مثل onStart() onStop()، ولكننا لا ننصح بذلك. إضافة هذا المنطق إلى مكوِّن مستقل وواعٍ لمراحل النشاط، يتيح لك إعادة استخدام المكوِّن في أنشطة متعددة بدون الحاجة إلى تكرار الرمز البرمجي لمعرفة كيفية إنشاء مكوِّن يراعي مراحل النشاط، اطّلِع على التعامل مع مراحل النشاط باستخدام المكوّنات الواعية لمراحل النشاط:

onPause()

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

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

عندما ينتقل نشاط إلى الحالة "متوقف مؤقتًا"، يتم ربط أي مكوّن واعٍ لمراحل النشاط. إلى دورة حياة النشاط حدث ON_PAUSE. هذا هو المكان فإن مكونات دورة الحياة يمكن أن توقف أي وظيفة لا تحتاج إلى التشغيل عندما لا يكون المكوِّن في المقدمة، مثل إيقاف الكاميرا معاينة.

استخدِم الطريقة onPause() لإيقاف المحتوى مؤقتًا أو تعديل العمليات التي لا يمكنها الاستمرار أو التي قد تستمر في الإشراف، بينما يكون Activity في حالة الإيقاف المؤقت، وأنك تتوقع استئنافه قريبًا.

يمكنك أيضًا استخدام طريقة onPause() لإجراء ما يلي: إطلاق موارد النظام أو الأسماء المعرِّفة لأجهزة الاستشعار (مثل GPS) أو أي موارد تؤثر في عمر البطارية عندما يكون نشاطك متوقفًا مؤقتًا ولا يفعل المستخدم ذلك يحتاجون إليها.

ومع ذلك، وكما ورد في القسم الذي يتناول onResume()، قد يظل النشاط مرئيًا بالكامل إذا كان التطبيق في وضع النوافذ المتعددة. يمكنك استخدام onStop() بدلاً من onPause() لإلغاء الميزة أو تعديلها بالكامل. الموارد والعمليات المتعلقة بواجهة المستخدم لإتاحة وضع النوافذ المتعددة بشكل أفضل

المثال التالي على LifecycleObserver فالتفاعل مع حدث ON_PAUSE هو نظير الحدث السابق مثال على حدث "ON_RESUME"، ما يؤدي إلى رفع إصبعك عن الكاميرا التي يتم إعدادها بعد استلام الحدث ON_RESUME:

Kotlin

class CameraComponent : LifecycleObserver {
    ...
    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    fun releaseCamera() {
        camera?.release()
        camera = null
    }
    ...
}

Java

public class JavaCameraComponent implements LifecycleObserver {
    ...
    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    public void releaseCamera() {
        if (camera != null) {
            camera.release();
            camera = null;
        }
    }
    ...
}

يضع هذا المثال رمز إصدار الكاميرا بعد تم استلام حدث ON_PAUSE من خلال LifecycleObserver.

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

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

إكمال طريقة onPause() لا يعني ذلك أن النشاط يترك حالة "متوقف مؤقتًا". بدلاً من ذلك، فإن النشاط يظل في هذه الحالة حتى يتم استئناف النشاط أو يصبح تمامًا غير مرئية للمستخدم. وإذا تم استئناف النشاط، يستدعي النظام مرة أخرى معاودة الاتصال onResume().

إذا كانت يعود النشاط من الحالة "متوقف مؤقتًا" إلى حالة "الاستئناف"، ويحافظ النظام على المثيل Activity المقيم في الذاكرة، ويسحب هذا الحدث عندما يستدعي النظام onResume(). في هذا السيناريو، لا تحتاج إلى إعادة تهيئة المكونات التي تم إنشاؤها أثناء أي من طرق معاودة الاتصال التي تؤدي إلى حالة الاستئناف. وإذا أصبح النشاط غير مرئي تمامًا، فسيستدعي النظام onStop()

onStop()

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

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

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

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

Kotlin

override fun onStop() {
    // Call the superclass method first.
    super.onStop()

    // Save the note's current draft, because the activity is stopping
    // and we want to be sure the current note progress isn't lost.
    val values = ContentValues().apply {
        put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText())
        put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle())
    }

    // Do this update in background on an AsyncQueryHandler or equivalent.
    asyncQueryHandler.startUpdate(
            token,     // int token to correlate calls
            null,      // cookie, not used here
            uri,       // The URI for the note to update.
            values,    // The map of column names and new values to apply to them.
            null,      // No SELECT criteria are used.
            null       // No WHERE columns are used.
    )
}

Java

@Override
protected void onStop() {
    // Call the superclass method first.
    super.onStop();

    // Save the note's current draft, because the activity is stopping
    // and we want to be sure the current note progress isn't lost.
    ContentValues values = new ContentValues();
    values.put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText());
    values.put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle());

    // Do this update in background on an AsyncQueryHandler or equivalent.
    asyncQueryHandler.startUpdate (
            mToken,  // int token to correlate calls
            null,    // cookie, not used here
            uri,    // The URI for the note to update.
            values,  // The map of column names and new values to apply to them.
            null,    // No SELECT criteria are used.
            null     // No WHERE columns are used.
    );
}

يستخدم نموذج التعليمة البرمجية السابق SQLite مباشرةً. ومع ذلك، ننصحك باستخدام ميزة "غرفة،" وهي مكتبة تثبيت توفر طبقة تجريدية فوق SQLite. للتعلّم مزيد من المعلومات حول مزايا استخدام الغرفة وطريقة تنفيذها في تطبيقك اطّلِع على مكتبة مدة الإقامة في الغرفة الدليل.

عندما يدخل نشاطك في حالة "متوقف"، تُعرَض في Activity محفوظًا في الذاكرة: فإنه يحافظ على جميع بيانات الحالة للحصول على معلومات، ولكن لا يتم إرفاقها بمدير النوافذ. عندما يبدأ النشاط ، فإنه يتذكر هذه المعلومات.

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

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

من الحالة "متوقف"، إما أن يعود النشاط للتفاعل مع أو انتهى النشاط ويختفي. إذا جاء النشاط رجوع، يستدعي النظام onRestart(). في حال انتهاء تشغيل "Activity"، يطلب النظام الاتصال. onDestroy()

onDestroy()

يتم استدعاء onDestroy() قبل ويتم التخلص من نشاطك. يستدعي النظام معاودة الاتصال هذه لأحد السببين التاليين:

  1. انتهاء النشاط، لأنّ المستخدم يرفض تمامًا نشاط أو بسبب يجري حاليًا استخدام finish() استدعينا النشاط.
  2. يتسبّب النظام في إتلاف النشاط مؤقتًا بسبب عملية الضبط. التغيير، مثل تدوير الجهاز أو الدخول في وضع النوافذ المتعددة.

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

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

إذا لم تتم إعادة إنشاء Activity، سيحمل ViewModel السمة تم استدعاء طريقة onCleared()، حيث يمكنها تنظيف أي بيانات يحتاج إليها قبل تدميرها. يمكنك التمييز بين هاتين السيناريوهين من خلال isFinishing().

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

يؤدي معاودة الاتصال onDestroy() إلى إصدار جميع الموارد التي لم يتم إصدارها قبل معاودة الاتصال، مثل onStop().

حالة النشاط وإخراجه من الذاكرة

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

احتمال التعرض للقتل حالة المعالجة حالة النشاط النهائي
الأدنى التي تظهر في المقدمة (بروز أو على وشك التركيز) تم استئناف العملية
ضعيفة مرئية (بدون تركيز) تم البدء/إيقاف مؤقت
جودة أعلى خلفية (غير مرئية) متوقفة
الأعلى فارغ تاريخ التدمير

الجدول 1. العلاقة بين دورة حياة العملية وحالة النشاط.

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

يمكن للمستخدم أيضًا إنهاء أي عملية باستخدام مدير التطبيقات، ضمن الإعدادات، لإغلاق التطبيق المقابل.

لمزيد من المعلومات حول العمليات، راجع العمليات وسلاسل المحادثات نظرة عامة.

حفظ حالة واجهة المستخدم المؤقتة واستعادتها

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

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

عندما تدمر قيود النظام النشاط، حافظ على الحالة المؤقتة لواجهة المستخدم لدى المستخدم باستخدام مجموعة من ViewModel، onSaveInstanceState()، و/أو التخزين المحلي. لمعرفة المزيد حول توقعات المستخدم مقارنة بالنظام كيفية الحفاظ على أفضل بيانات حالة واجهة المستخدم المعقدة عبر النشاط الذي يبدأه النظام والعملية المميتة، راجع حفظ حالات واجهة المستخدم:

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

ملاحظة: لمزيد من المعلومات حول تغييرات الضبط، يمكنك حظر "النشاط". إذا لزم الأمر، وكيفية التفاعل مع تغييرات التهيئة هذه من عرض النظام وJetpack Compose، صفحة التعامل مع تغييرات الضبط.

حالة المثيل

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

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

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

والبيانات المحفوظة التي يستخدمها النظام لاستعادة حالة المثيل. إنها مجموعة من أزواج المفتاح/القيمة المخزّنة في كائن Bundle. بشكل افتراضي، يستخدم النظام حالة المثيل Bundle لحفظ المعلومات. حول كل عنصر View في تنسيق النشاط، مثل القيمة النصية التي تم إدخالها في التطبيق المصغَّر EditText.

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

ملاحظة: لكي يستعيد نظام Android حالة المشاهدات في نشاطك، يجب أن يكون لكل ملف شخصي معرّف فريد، السمة android:id.

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

حفظ حالة واجهة مستخدم بسيطة وخفيفة باستخدام onSaveInstanceState()

عند بدء توقف نشاطك، يستدعي النظام onSaveInstanceState() حتى يتمكن نشاطك من حفظ معلومات الحالة في حالة المثيل حُزم. يُحفظ التنفيذ التلقائي لهذه الطريقة طريقة العرض المؤقت معلومات عن حالة العرض الهرمي لطريقة عرض النشاط، مثل نص في تطبيق EditText المصغّر أو موضع الانتقال للأعلى أو للأسفل في التطبيق المصغّر ListView

لحفظ معلومات إضافية عن حالة المثيل من نشاطك، يمكنك إلغاء onSaveInstanceState() وإضافة أزواج المفتاح/القيمة إلى الكائن Bundle الذي يتم حفظه في حالة تلف نشاطك بشكل غير متوقع. عند الإلغاء onSaveInstanceState()، عليك استدعاء طريقة التنفيذ المتميزة إذا أردت في عملية التنفيذ التلقائية حفظ حالة التدرّج الهرمي لطريقة العرض. يظهر ذلك في المثال التالي:

Kotlin

override fun onSaveInstanceState(outState: Bundle?) {
    // Save the user's current game state.
    outState?.run {
        putInt(STATE_SCORE, currentScore)
        putInt(STATE_LEVEL, currentLevel)
    }

    // Always call the superclass so it can save the view hierarchy state.
    super.onSaveInstanceState(outState)
}

companion object {
    val STATE_SCORE = "playerScore"
    val STATE_LEVEL = "playerLevel"
}

Java

static final String STATE_SCORE = "playerScore";
static final String STATE_LEVEL = "playerLevel";
// ...


@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    // Save the user's current game state.
    savedInstanceState.putInt(STATE_SCORE, currentScore);
    savedInstanceState.putInt(STATE_LEVEL, currentLevel);

    // Always call the superclass so it can save the view hierarchy state.
    super.onSaveInstanceState(savedInstanceState);
}

ملاحظة: onSaveInstanceState() ليس يتم استدعاؤه عندما يغلق المستخدم النشاط صراحةً أو في حالات أخرى عند تسمّى finish().

لحفظ البيانات الدائمة، مثل تفضيلات المستخدم أو بيانات قاعدة البيانات، الاستفادة من الفرص المناسبة عندما يكون نشاطك في المقدّمة. وفي حال عدم ظهور أي فرصة من هذا القبيل، احفظ البيانات المستمرة أثناء onStop().

استعادة حالة واجهة مستخدم النشاط باستخدام حالة المثيل المحفوظة

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

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

يعرض مقتطف الرمز التالي كيفية استعادة بعض بيانات الحالة في onCreate():

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState) // Always call the superclass first

    // Check whether we're recreating a previously destroyed instance.
    if (savedInstanceState != null) {
        with(savedInstanceState) {
            // Restore value of members from saved state.
            currentScore = getInt(STATE_SCORE)
            currentLevel = getInt(STATE_LEVEL)
        }
    } else {
        // Probably initialize members with default values for a new instance.
    }
    // ...
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState); // Always call the superclass first

    // Check whether we're recreating a previously destroyed instance.
    if (savedInstanceState != null) {
        // Restore value of members from saved state.
        currentScore = savedInstanceState.getInt(STATE_SCORE);
        currentLevel = savedInstanceState.getInt(STATE_LEVEL);
    } else {
        // Probably initialize members with default values for a new instance.
    }
    // ...
}

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

Kotlin

override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
    // Always call the superclass so it can restore the view hierarchy.
    super.onRestoreInstanceState(savedInstanceState)

    // Restore state members from saved instance.
    savedInstanceState?.run {
        currentScore = getInt(STATE_SCORE)
        currentLevel = getInt(STATE_LEVEL)
    }
}

Java

public void onRestoreInstanceState(Bundle savedInstanceState) {
    // Always call the superclass so it can restore the view hierarchy.
    super.onRestoreInstanceState(savedInstanceState);

    // Restore state members from saved instance.
    currentScore = savedInstanceState.getInt(STATE_SCORE);
    currentLevel = savedInstanceState.getInt(STATE_LEVEL);
}

تحذير: دع دائمًا التنفيذ الفائق onRestoreInstanceState() وبالتالي، يمكن لعملية التنفيذ التلقائية أن تستعيد حالة التدرّج الهرمي لطريقة العرض.

التنقّل بين الأنشطة

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

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

بدء نشاط من نشاط آخر

غالبًا ما يحتاج النشاط إلى بدء نشاط آخر في مرحلة ما. هذا الحاجة عندما يحتاج أحد التطبيقات إلى الانتقال من الشاشة الحالية إلى جديدة.

اعتمادًا على ما إذا كان نشاطك يريد الحصول على نتيجة من النشاط الجديد أم لا على وشك أن يبدأ، تبدأ النشاط الجديد باستخدام إما startActivity() الطريقة أو startActivityForResult() . وفي كلتا الحالتين، تمرِّر عنصر Intent.

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

startActivity()

إذا كان النشاط الذي بدأ حديثًا لا يحتاج إلى عرض نتيجة، يمكن أن يبدأ النشاط الحالي من خلال استدعاء startActivity() .

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

Kotlin

val intent = Intent(this, SignInActivity::class.java)
startActivity(intent)

Java

Intent intent = new Intent(this, SignInActivity.class);
startActivity(intent);

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

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

Kotlin

val intent = Intent(Intent.ACTION_SEND).apply {
    putExtra(Intent.EXTRA_EMAIL, recipientArray)
}
startActivity(intent)

Java

Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_EMAIL, recipientArray);
startActivity(intent);

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

startActivityForResult()

في بعض الأحيان، تريد الحصول على نتيجة من نشاط عند انتهائه. على سبيل المثال، يمكنك أن تبدأ نشاط يتيح للمستخدم اختيار شخص في قائمة جهات الاتصال. عند انتهائه، تُرجع للشخص الذي تم اختياره. للقيام بذلك، يمكنك استدعاء دالة الرسم startActivityForResult(Intent, int) حيث تحدد معلمة العدد الصحيح الاستدعاء.

يهدف هذا المعرّف إلى التمييز بين الطلبات المتعددة startActivityForResult(Intent, int) من النشاط نفسه. ليس معرّفًا عموميًا وليست معرّضة لخطر التعارض مع التطبيقات أو الأنشطة الأخرى. تعود النتيجة من خلال onActivityResult(int, int, Intent) .

عند الخروج من نشاط طفل، يمكنه طلب setResult(int) من أجل بإرجاع البيانات إلى الأصل. يجب أن يوفر النشاط الفرعي رمز نتيجة، ويمكن أن يكون هذا الرمز هو النتائج العادية. RESULT_CANCELED أو RESULT_OK أو أي قيم مخصّصة بدءًا من RESULT_FIRST_USER

بالإضافة إلى ذلك، يستطيع النشاط الفرعي عرض Intent بشكل اختياري. يحتوي على أي بيانات إضافية يريدها. يستخدم النشاط الوالد onActivityResult(int, int, Intent) مع معرّف العدد الصحيح، فالنشاط الرئيسي أصلاً معينة، لتلقي المعلومات.

إذا فشل أحد الأنشطة الفرعية لأي سبب من الأسباب، مثل تعطُّل الخدمات، ينبغي لأحد الوالدين يتلقى نشاط نتيجة مع الرمز RESULT_CANCELED.

Kotlin

class MyActivity : Activity() {
    // ...

    override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
        if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
            // When the user center presses, let them pick a contact.
            startActivityForResult(
                    Intent(Intent.ACTION_PICK,Uri.parse("content://contacts")),
                    PICK_CONTACT_REQUEST)
            return true
        }
        return false
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {
        when (requestCode) {
            PICK_CONTACT_REQUEST ->
                if (resultCode == RESULT_OK) {
                    // A contact was picked. Display it to the user.
                    startActivity(Intent(Intent.ACTION_VIEW, intent?.data))
                }
        }
    }

    companion object {
        internal val PICK_CONTACT_REQUEST = 0
    }
}

Java

public class MyActivity extends Activity {
     // ...

     static final int PICK_CONTACT_REQUEST = 0;

     public boolean onKeyDown(int keyCode, KeyEvent event) {
         if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
             // When the user center presses, let them pick a contact.
             startActivityForResult(
                 new Intent(Intent.ACTION_PICK,
                 new Uri("content://contacts")),
                 PICK_CONTACT_REQUEST);
            return true;
         }
         return false;
     }

     protected void onActivityResult(int requestCode, int resultCode,
             Intent data) {
         if (requestCode == PICK_CONTACT_REQUEST) {
             if (resultCode == RESULT_OK) {
                 // A contact was picked. Display it to the user.
                 startActivity(new Intent(Intent.ACTION_VIEW, data));
             }
         }
     }
 }

تنسيق الأنشطة

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

إن ترتيب استدعاءات دورة الحياة محدد جيدًا، لا سيما عندما يكون النشاطين في نفس العملية - بمعنى آخر، نفس التطبيق - ويبدأ أحدهما الآخر. وإليك ترتيب العمليات التي تحدث عندما يبدأ النشاط "أ" النشاط "ب":

  1. يتم تنفيذ الطريقة onPause() للنشاط "أ".
  2. النشاط "ب" onCreate()، onStart() و يتم تنفيذ طرق onResume() بالتسلسل. يركز النشاط "ب" الآن على المستخدم.
  3. إذا لم يعُد النشاط "أ" مرئيًا على الشاشة، يتم تنفيذ طريقة onStop() الخاصة به.

يتيح لك هذا التسلسل من استدعاءات مراحل النشاط إدارة انتقال المعلومات من نشاط إلى آخر.