چرخه حیات فعالیت

هنگامی که کاربر از طریق برنامه شما، خارج و به آن باز می گردد، نمونه های Activity در برنامه شما از حالت های مختلف در چرخه عمر خود عبور می کنند. کلاس Activity تعدادی فراخوان ارائه می‌کند که به اکتیویتی اطلاع می‌دهد که یک حالت تغییر می‌کند یا اینکه سیستم در حال ایجاد، توقف، یا از سرگیری یک فعالیت یا از بین بردن فرآیندی است که فعالیت در آن قرار دارد.

در روش‌های برگشت به تماس چرخه حیات، می‌توانید نحوه رفتار فعالیت خود را هنگام خروج کاربر و ورود مجدد به فعالیت اعلام کنید. به عنوان مثال، اگر در حال ساخت یک پخش کننده ویدیوی استریم هستید، ممکن است وقتی کاربر به برنامه دیگری سوئیچ می کند، ویدیو را موقتاً متوقف کرده و اتصال شبکه را قطع کنید. وقتی کاربر برگشت، می‌توانید دوباره به شبکه متصل شوید و به کاربر اجازه دهید ویدیو را از همان نقطه از سر بگیرد.

هر پاسخ به تماس به شما امکان می دهد کار خاصی را انجام دهید که برای تغییر وضعیت مشخص مناسب است. انجام کار مناسب در زمان مناسب و مدیریت صحیح انتقال ها، برنامه شما را قوی تر و کارآمدتر می کند. به عنوان مثال، اجرای خوب بازگشت به تماس چرخه حیات می تواند به برنامه شما کمک کند تا از موارد زیر جلوگیری کند:

  • اگر کاربر هنگام استفاده از برنامه شما یک تماس تلفنی دریافت کند یا به برنامه دیگری سوئیچ کند خراب می شود.
  • مصرف منابع ارزشمند سیستم زمانی که کاربر بطور فعال از آن استفاده نمی کند.
  • اگر کاربر برنامه شما را ترک کند و بعداً به آن بازگردد، پیشرفت کاربر را از دست می‌دهد.
  • هنگام چرخش صفحه بین جهت افقی و عمودی، از کار افتادن یا از دست دادن پیشرفت کاربر.

این سند چرخه حیات فعالیت را به طور مفصل توضیح می دهد. سند با توصیف پارادایم چرخه حیات آغاز می شود. در مرحله بعد، هر یک از تماس‌های برگشتی را توضیح می‌دهد: در حین اجرا چه اتفاقی می‌افتد و چه چیزی باید در طول آنها پیاده‌سازی شود.

سپس به طور خلاصه رابطه بین وضعیت فعالیت و آسیب پذیری یک فرآیند در برابر کشته شدن توسط سیستم را معرفی می کند. در نهایت، چندین موضوع مربوط به انتقال بین حالت‌های فعالیت را مورد بحث قرار می‌دهد.

برای اطلاعات در مورد مدیریت چرخه عمر، از جمله راهنمایی در مورد بهترین شیوه‌ها، به مدیریت چرخه‌های عمر با مؤلفه‌های آگاه از چرخه حیات و وضعیت‌های Save UI مراجعه کنید. برای یادگیری نحوه طراحی یک برنامه قوی و با کیفیت تولید با استفاده از فعالیت‌ها در ترکیب با اجزای معماری، به راهنمای معماری برنامه مراجعه کنید.

مفاهیم چرخه فعالیت فعالیت

برای پیمایش انتقال بین مراحل چرخه حیات اکتیویتی، کلاس Activity یک مجموعه اصلی از شش فراخوان ارائه می‌کند: onCreate() , onStart() , onResume() , onPause() , onStop() و onDestroy() . سیستم هر یک از این تماس ها را با وارد شدن فعالیت به حالت جدید فراخوانی می کند.

شکل 1 نمایش بصری این پارادایم را نشان می دهد.

شکل 1. یک تصویر ساده از چرخه حیات فعالیت.

هنگامی که کاربر شروع به ترک فعالیت می کند، سیستم روش هایی را برای از بین بردن فعالیت فراخوانی می کند. در برخی موارد، فعالیت فقط تا حدی از بین می‌رود و همچنان در حافظه باقی می‌ماند، مانند زمانی که کاربر به برنامه دیگری سوئیچ می‌کند. در این موارد، فعالیت همچنان می تواند به پیش زمینه بازگردد.

اگر کاربر به فعالیت برگردد، از جایی که کاربر فعالیت را متوقف کرده است، از سر گرفته می شود. با چند استثنا، برنامه‌ها از شروع فعالیت‌ها در هنگام اجرا در پس‌زمینه محدود هستند.

احتمال از بین بردن یک فرآیند مشخص توسط سیستم، همراه با فعالیت های موجود در آن، به وضعیت فعالیت در آن زمان بستگی دارد. برای اطلاعات بیشتر در مورد رابطه بین حالت و آسیب پذیری در برابر خروج، به بخش مربوط به وضعیت فعالیت و خروج از حافظه مراجعه کنید.

بسته به پیچیدگی فعالیت خود، احتمالاً نیازی به پیاده سازی تمام روش های چرخه حیات ندارید. با این حال، مهم است که هر یک را درک کنید و مواردی را اجرا کنید که باعث می‌شود برنامه شما مطابق انتظار کاربران عمل کند.

تماس های چرخه حیات

این بخش اطلاعات مفهومی و پیاده سازی را در مورد روش های برگشت تماس مورد استفاده در چرخه حیات فعالیت ارائه می دهد.

برخی از اقدامات به روش های چرخه حیات فعالیت تعلق دارند. با این حال، کدی را قرار دهید که اعمال یک جزء وابسته را به جای روش چرخه حیات فعالیت، در کامپوننت پیاده سازی کند. برای رسیدن به این هدف، باید چرخه حیات جزء وابسته را آگاه کنید. برای یادگیری نحوه آگاه کردن اجزای وابسته به چرخه عمر، به مدیریت چرخه های زندگی با اجزای مربوط به چرخه حیات مراجعه کنید.

onCreate()

شما باید این callback را پیاده سازی کنید، که وقتی سیستم برای اولین بار فعالیت را ایجاد می کند، فعال می شود. در ایجاد اکتیویتی، اکتیویتی وارد حالت Created می شود. در متد onCreate() ، منطق اولیه راه‌اندازی برنامه را انجام دهید که فقط یک بار در طول عمر فعالیت اتفاق می‌افتد.

برای مثال، پیاده‌سازی onCreate() شما ممکن است داده‌ها را به لیست‌ها متصل کند، فعالیت را با ViewModel مرتبط کند و برخی از متغیرهای محدوده کلاس را نمونه‌سازی کند. این متد پارامتر savedInstanceState را دریافت می کند که یک شی Bundle است که شامل حالت ذخیره شده قبلی اکتیویتی است. اگر اکتیویتی قبلاً وجود نداشته است، مقدار شی Bundle null است.

اگر مؤلفه‌ای از چرخه حیات دارید که به چرخه حیات فعالیت شما متصل است، رویداد ON_CREATE را دریافت می‌کند. روش مشروح شده با @OnLifecycleEvent نامیده می شود تا مؤلفه آگاه از چرخه حیات شما بتواند هر کد راه اندازی را که برای حالت ایجاد شده نیاز دارد انجام دهد.

مثال زیر از متد onCreate() تنظیمات اساسی برای فعالیت را نشان می دهد، مانند اعلام رابط کاربری (تعریف شده در یک فایل طرح بندی XML)، تعریف متغیرهای عضو، و پیکربندی برخی از UI. در این مثال، فایل طرح‌بندی XML شناسه منبع فایل R.layout.main_activity به setContentView() ارسال می‌کند.

کاتلین

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)
}

جاوا

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 ، یک سلسله مراتب view ایجاد کنید. سپس با ارسال root ViewGroup به setContentView() از آن چیدمان استفاده می کنید. برای اطلاعات بیشتر در مورد ایجاد رابط کاربری، به مستندات رابط کاربری مراجعه کنید.

فعالیت شما در حالت ایجاد شده باقی نمی ماند. پس از اتمام اجرای متد onCreate() ، اکتیویتی وارد حالت Started شده و سیستم متدهای onStart() و onResume() را به صورت متوالی فراخوانی می کند.

onStart()

وقتی اکتیویتی وارد حالت Started شد، سیستم onStart() را فراخوانی می کند. این تماس باعث می‌شود تا زمانی که برنامه برای ورود به پیش‌زمینه و تعاملی شدن فعالیت آماده می‌شود، فعالیت را برای کاربر قابل مشاهده می‌کند. به عنوان مثال، این روش جایی است که کدی که UI را حفظ می کند مقداردهی اولیه می شود.

وقتی فعالیت به حالت شروع می‌رود، هر مؤلفه آگاه از چرخه حیات مرتبط با چرخه حیات فعالیت، رویداد ON_START را دریافت می‌کند.

متد onStart() به سرعت کامل می شود و مانند حالت Created، فعالیت در حالت شروع باقی نمی ماند. پس از اتمام این callback، اکتیویتی وارد حالت Resumed می شود و سیستم متد onResume() فراخوانی می کند.

onResume()

زمانی که اکتیویتی وارد حالت Resumed می شود، در پیش زمینه قرار می گیرد و سیستم فراخوانی onResume() فراخوانی می کند. این حالتی است که در آن برنامه با کاربر تعامل دارد. برنامه در این حالت باقی می ماند تا زمانی که اتفاقی بیفتد که تمرکز را از برنامه دور کند، مانند دستگاهی که یک تماس تلفنی دریافت می کند، کاربر به فعالیت دیگری پیمایش می کند یا صفحه دستگاه خاموش می شود.

هنگامی که فعالیت به وضعیت Resumed منتقل می‌شود، هر مؤلفه آگاه از چرخه حیات مرتبط با چرخه حیات فعالیت، رویداد ON_RESUME را دریافت می‌کند. اینجاست که اجزای چرخه حیات می‌توانند هر عملکردی را که نیاز به اجرا دارد در حالی که مؤلفه قابل مشاهده است و در پیش‌زمینه است، مانند شروع پیش‌نمایش دوربین، فعال می‌کند.

هنگامی که یک رویداد وقفه ای رخ می دهد، اکتیویتی وارد حالت Paused می شود و سیستم فراخوانی onPause() را فراخوانی می کند.

اگر اکتیویتی از حالت Paused به حالت Resumed برگردد، سیستم یک بار دیگر متد onResume() فراخوانی می کند. به همین دلیل، onResume() برای مقداردهی اولیه مولفه هایی که در طول onPause() آزاد می کنید و هر مقدار اولیه که باید هر بار که اکتیویتی وارد حالت Resumed می شود انجام شود، پیاده سازی کنید.

در اینجا مثالی از یک مؤلفه آگاه از چرخه حیات است که هنگامی که مؤلفه رویداد ON_RESUME را دریافت می کند، به دوربین دسترسی پیدا می کند:

کاتلین

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

جاوا

public class CameraComponent implements LifecycleObserver {

    ...

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

زمانی که LifecycleObserver رویداد ON_RESUME را دریافت کرد، کد قبلی دوربین را مقداردهی اولیه می کند. با این حال، در حالت چند پنجره‌ای، فعالیت شما ممکن است کاملاً قابل مشاهده باشد حتی زمانی که در حالت توقف قرار دارد. به عنوان مثال، هنگامی که برنامه در حالت چند پنجره ای است و کاربر روی پنجره ای که شامل فعالیت شما نیست ضربه می زند، فعالیت شما به حالت Paused منتقل می شود.

اگر می‌خواهید دوربین فقط زمانی فعال باشد که برنامه از سر گرفته شود (در پیش‌زمینه قابل مشاهده و فعال است)، پس از رویداد ON_RESUME که قبلا نشان داده شده بود، دوربین را مقداردهی اولیه کنید. اگر می خواهید دوربین را در زمانی که فعالیت متوقف شده اما قابل مشاهده است، مانند حالت چند پنجره ای فعال نگه دارید، پس از رویداد ON_START دوربین را مقداردهی اولیه کنید.

با این حال، فعال بودن دوربین در زمانی که فعالیت شما متوقف شده است، ممکن است دسترسی به دوربین را به برنامه Resumed دیگر در حالت چند پنجره ای منع کند. گاهی اوقات لازم است دوربین را در زمانی که فعالیت شما متوقف شده است فعال نگه دارید، اما در صورت انجام این کار ممکن است تجربه کلی کاربر را کاهش دهد.

به همین دلیل، به دقت فکر کنید که در کدام قسمت از چرخه حیات، کنترل منابع سیستم مشترک در زمینه حالت چند پنجره ای مناسب تر است. برای کسب اطلاعات بیشتر در مورد پشتیبانی از حالت چند پنجره ای، به پشتیبانی چند پنجره ای مراجعه کنید.

صرف نظر از اینکه کدام رویداد build-up را برای انجام عملیات اولیه سازی انتخاب می کنید، مطمئن شوید که از رویداد چرخه حیات مربوطه برای انتشار منبع استفاده می کنید. اگر چیزی را بعد از رویداد ON_START مقداردهی اولیه کردید، آن را پس از رویداد ON_STOP آزاد یا خاتمه دهید. اگر بعد از رویداد ON_RESUME مقداردهی اولیه کنید، پس از رویداد ON_PAUSE رها کنید.

قطعه کد قبلی کد اولیه سازی دوربین را در یک جزء از چرخه حیات قرار می دهد. در عوض می‌توانید این کد را مستقیماً در فراخوان‌های چرخه حیات فعالیت، مانند onStart() و onStop() قرار دهید، اما ما این را توصیه نمی‌کنیم. افزودن این منطق به یک مؤلفه مستقل و آگاه از چرخه حیات، به شما امکان می دهد بدون نیاز به تکرار کد، از مؤلفه در چندین فعالیت استفاده کنید. برای یادگیری نحوه ایجاد یک مؤلفه آگاه از چرخه حیات، به مدیریت چرخه زندگی با مؤلفه‌های آگاه از چرخه حیات رجوع کنید.

onPause()

سیستم این روش را به عنوان اولین نشانه ای که کاربر از فعالیت شما خارج می شود نام می برد، اگرچه همیشه به این معنی نیست که فعالیت در حال نابودی است. این نشان می دهد که فعالیت دیگر در پیش زمینه نیست، اما اگر کاربر در حالت چند پنجره ای باشد همچنان قابل مشاهده است. دلایل مختلفی وجود دارد که چرا یک فعالیت ممکن است به این حالت وارد شود:

  • رویدادی که اجرای برنامه را قطع می‌کند، همانطور که در بخش مربوط به پاسخ تماس ()onResume توضیح داده شد، فعالیت فعلی را متوقف می‌کند. این شایع ترین مورد است.
  • در حالت چند پنجره ای، در هر زمان فقط یک برنامه فوکوس دارد و سیستم همه برنامه های دیگر را متوقف می کند.
  • باز شدن یک فعالیت جدید و نیمه شفاف، مانند یک گفتگو، فعالیتی را که پوشش می دهد متوقف می کند. تا زمانی که فعالیت تا حدی قابل مشاهده باشد اما در فوکوس نباشد، متوقف می شود.

وقتی یک فعالیت به حالت Paused منتقل می‌شود، هر مؤلفه آگاه از چرخه حیات مرتبط با چرخه حیات فعالیت، رویداد ON_PAUSE را دریافت می‌کند. اینجاست که اجزای چرخه حیات می‌توانند هر عملکردی را که نیازی به اجرا ندارد، در حالی که مؤلفه در پیش‌زمینه نیست، متوقف کند، مانند توقف پیش‌نمایش دوربین.

از متد onPause() برای توقف یا تنظیم عملیاتی استفاده کنید که نمی‌تواند ادامه یابد یا ممکن است در حالت اعتدال ادامه یابد، در حالی که Activity در حالت Paused است و انتظار دارید به زودی از سر گرفته شود.

همچنین می‌توانید از روش onPause() برای آزاد کردن منابع سیستم، دستگیره‌های حسگرها (مانند GPS)، یا هر منبعی که بر عمر باتری تأثیر می‌گذارد، در زمانی که فعالیت شما متوقف شده و کاربر به آن‌ها نیاز ندارد، استفاده کنید.

با این حال، همانطور که در بخش onResume() ذکر شد، اگر برنامه در حالت چند پنجره ای باشد، ممکن است یک فعالیت Paused همچنان به طور کامل قابل مشاهده باشد. استفاده از onStop() را به جای onPause() برای آزادسازی کامل یا تنظیم منابع و عملیات مربوط به UI برای پشتیبانی بهتر از حالت چند پنجره ای در نظر بگیرید.

مثال زیر از یک LifecycleObserver که به رویداد ON_PAUSE واکنش نشان می‌دهد، همتای مثال رویداد قبلی ON_RESUME است که دوربینی را آزاد می‌کند که پس از دریافت رویداد ON_RESUME مقداردهی اولیه می‌شود:

کاتلین

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

جاوا

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() به این معنی نیست که فعالیت از حالت Paused خارج می شود. در عوض، فعالیت در این حالت باقی می ماند تا زمانی که فعالیت از سر گرفته شود یا کاملاً برای کاربر نامرئی شود. اگر فعالیت از سر گرفته شود، سیستم یک بار دیگر فراخوانی onResume() فراخوانی می کند.

اگر اکتیویتی از حالت Paused به حالت Resumed برگردد، سیستم نمونه Activity را در حافظه نگه می دارد و زمانی که سیستم onResume() را فراخوانی می کند، آن نمونه را به یاد می آورد. در این سناریو، نیازی به راه‌اندازی مجدد مؤلفه‌های ایجاد شده در طی هر یک از روش‌های برگشت به حالت Resumed ندارید. اگر فعالیت به طور کامل نامرئی شود، سیستم onStop() را فراخوانی می کند.

onStop()

هنگامی که فعالیت شما دیگر برای کاربر قابل مشاهده نیست، وارد حالت Stopped می شود و سیستم پاسخ onStop() را فراخوانی می کند. این می تواند زمانی رخ دهد که یک فعالیت تازه راه اندازی شده کل صفحه را پوشش دهد. هنگامی که فعالیت به پایان می رسد و در شرف پایان است، سیستم onStop() را فراخوانی می کند.

هنگامی که فعالیت به حالت توقف حرکت می کند، هر مؤلفه آگاه از چرخه حیات مرتبط با چرخه حیات فعالیت، رویداد ON_STOP را دریافت می کند. اینجاست که اجزای چرخه حیات می‌توانند هر عملکردی را که نیازی به اجرا ندارد، در حالی که مؤلفه روی صفحه قابل مشاهده نیست، متوقف کند.

در متد onStop() منابعی را که مورد نیاز نیستند آزاد یا تنظیم کنید در حالی که برنامه برای کاربر قابل مشاهده نیست. برای مثال، برنامه شما ممکن است انیمیشن‌ها را متوقف کند یا از به‌روزرسانی‌های موقعیت مکانی با دانه‌ریزی به درشت دانه تغییر کند. استفاده از onStop() به جای onPause() به این معنی است که کار مرتبط با UI ادامه می یابد، حتی زمانی که کاربر فعالیت شما را در حالت چند پنجره ای مشاهده می کند.

همچنین، از onStop() برای انجام عملیات خاموش کردن نسبتا فشرده CPU استفاده کنید. به عنوان مثال، اگر نمی توانید زمان بهتری برای ذخیره اطلاعات در پایگاه داده پیدا کنید، ممکن است این کار را در طول onStop() انجام دهید. مثال زیر پیاده‌سازی onStop() را نشان می‌دهد که محتویات یک یادداشت پیش‌نویس را در ذخیره‌سازی دائمی ذخیره می‌کند:

کاتلین

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.
    )
}

جاوا

@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 استفاده می کند. با این حال، توصیه می کنیم از Room استفاده کنید، یک کتابخانه پایدار که یک لایه انتزاعی را روی SQLite فراهم می کند. برای کسب اطلاعات بیشتر در مورد مزایای استفاده از Room و نحوه پیاده سازی Room در برنامه خود، به راهنمای Room Persistence Library مراجعه کنید.

وقتی اکتیویتی شما وارد حالت توقف شد، شیء Activity در حافظه باقی می ماند: تمام اطلاعات وضعیت و اعضا را حفظ می کند، اما به مدیر پنجره متصل نمی شود. هنگامی که فعالیت از سر گرفته می شود، این اطلاعات را به یاد می آورد.

نیازی نیست مؤلفه‌های ایجاد شده در طول هر یک از روش‌های برگشت به حالت Resumed را دوباره راه‌اندازی کنید. این سیستم همچنین وضعیت فعلی هر شی View را در طرح‌بندی ردیابی می‌کند، بنابراین اگر کاربر متنی را در ویجت EditText وارد کند، آن محتوا حفظ می‌شود، بنابراین نیازی به ذخیره و بازیابی آن نیست.

توجه: هنگامی که فعالیت شما متوقف شود، اگر سیستم نیاز به بازیابی حافظه داشته باشد، ممکن است سیستم فرآیندی را که شامل فعالیت است از بین ببرد. حتی اگر سیستم در حین توقف فعالیت، فرآیند را از بین ببرد، سیستم همچنان وضعیت اشیاء View را حفظ می‌کند، مانند متن در یک ویجت EditText ، در یک Bundle - لکه‌ای از جفت‌های کلید-مقدار - و اگر کاربر آنها را بازیابی کند. به فعالیت بازمی گردد. برای اطلاعات بیشتر در مورد بازیابی فعالیتی که کاربر به آن برمی گردد، به بخش مربوط به ذخیره و بازیابی وضعیت مراجعه کنید.

از حالت توقف، فعالیت یا برای تعامل با کاربر باز می گردد، یا فعالیت به پایان می رسد و از بین می رود. اگر اکتیویتی بازگردد، سیستم onRestart() را فراخوانی می کند. اگر Activity به پایان برسد، سیستم onDestroy() فرا می خواند.

onDestroy()

onDestroy() قبل از نابودی اکتیویتی فراخوانی می شود. سیستم به یکی از دو دلیل این تماس را فراخوانی می کند:

  1. به دلیل رد کامل اکتیویتی توسط کاربر یا به دلیل finish() بر روی اکتیویتی، فعالیت در حال اتمام است.
  2. سیستم به دلیل تغییر پیکربندی، مانند چرخش دستگاه یا وارد شدن به حالت چند پنجره ای، به طور موقت فعالیت را از بین می برد.

وقتی اکتیویتی به حالت تخریب شده حرکت می کند، هر جزء آگاه از چرخه حیات مرتبط با چرخه حیات فعالیت، رویداد ON_DESTROY را دریافت می کند. اینجاست که اجزای چرخه حیات می توانند هر چیزی را که نیاز دارند قبل از از بین رفتن Activity پاکسازی کنند.

به جای قرار دادن منطق در Activity خود برای تعیین دلیل نابودی آن، از یک شی ViewModel استفاده کنید تا داده های view مربوطه را برای Activity خود داشته باشد. اگر Activity به دلیل تغییر پیکربندی دوباره ایجاد شود، ViewModel نیازی به انجام کاری ندارد، زیرا حفظ می شود و به نمونه Activity بعدی داده می شود.

اگر Activity دوباره ایجاد نشود، ViewModel متد onCleared() را فراخوانی می‌کند، جایی که می‌تواند هر داده‌ای را که نیاز دارد قبل از نابود شدن پاک کند. با متد isFinishing() می توانید بین این دو سناریو تمایز قائل شوید.

اگر اکتیویتی در حال اتمام است، onDestroy() آخرین تماس چرخه حیات است که اکتیویتی دریافت می کند. اگر onDestroy() به عنوان نتیجه تغییر پیکربندی فراخوانی شود، سیستم بلافاصله یک نمونه فعالیت جدید ایجاد می کند و سپس onCreate() روی آن نمونه جدید در پیکربندی جدید فراخوانی می کند.

onDestroy() همه منابعی را که توسط callback های قبلی منتشر نشده اند، مانند onStop() آزاد می کند.

وضعیت فعالیت و خروج از حافظه

سیستم زمانی که نیاز به آزادسازی رم دارد، فرآیندها را از بین می برد. احتمال اینکه سیستم یک فرآیند معین را از بین ببرد به وضعیت فرآیند در آن زمان بستگی دارد. وضعیت فرآیند به نوبه خود به وضعیت فعالیت در حال اجرا در فرآیند بستگی دارد. جدول 1 همبستگی بین وضعیت فرآیند، وضعیت فعالیت و احتمال نابودی فرآیند توسط سیستم را نشان می دهد. این جدول فقط در صورتی اعمال می شود که یک فرآیند انواع دیگر اجزای برنامه را اجرا نکند.

احتمال کشته شدن وضعیت فرآیند وضعیت فعالیت نهایی
پایین ترین پیش زمینه (داشتن یا در حال رسیدن به تمرکز) از سر گرفته شد
پایین قابل مشاهده (بدون تمرکز) شروع/مکث شد
بالاتر پس زمینه (نامرئی) متوقف شد
بالاترین خالی نابود شد

جدول 1. رابطه بین چرخه حیات فرآیند و وضعیت فعالیت.

این سیستم هرگز یک فعالیت را مستقیماً برای آزاد کردن حافظه از بین نمی برد. درعوض، فرآیندی را که اکتیویتی در آن اجرا می‌شود، از بین می‌برد و نه تنها اکتیویتی را از بین می‌برد، بلکه هر چیز دیگری را که در این فرآیند اجرا می‌شود نیز از بین می‌برد. برای آشنایی با نحوه حفظ و بازیابی وضعیت رابط کاربری فعالیت خود در هنگام وقوع مرگ فرآیند آغاز شده توسط سیستم، به بخش مربوط به ذخیره و بازیابی وضعیت مراجعه کنید.

کاربر همچنین می‌تواند با استفاده از Application Manager در زیر تنظیمات، یک فرآیند را برای حذف برنامه مربوطه بکشد.

برای اطلاعات بیشتر در مورد فرآیندها، به بررسی اجمالی فرآیندها و موضوعات مراجعه کنید.

ذخیره و بازیابی حالت گذرا UI

کاربر انتظار دارد که وضعیت رابط کاربری یک فعالیت در طول یک تغییر پیکربندی، مانند چرخش یا تغییر حالت چند پنجره ای، ثابت بماند. با این حال، هنگامی که چنین تغییری در پیکربندی اتفاق می‌افتد، سیستم به طور پیش‌فرض فعالیت را از بین می‌برد و هر حالت رابط کاربری ذخیره شده در نمونه فعالیت را پاک می‌کند.

به طور مشابه، یک کاربر انتظار دارد که اگر به طور موقت از برنامه شما به یک برنامه دیگر برود و بعداً به برنامه شما بازگردد، وضعیت رابط کاربری یکسان باقی بماند. با این حال، سیستم می تواند فرآیند برنامه شما را در زمانی که کاربر دور است و فعالیت شما متوقف شده است، از بین ببرد.

هنگامی که محدودیت‌های سیستم فعالیت را از بین می‌برند، حالت گذرا UI کاربر را با استفاده از ترکیبی از ViewModel ، onSaveInstanceState() و/یا ذخیره‌سازی محلی حفظ کنید. برای کسب اطلاعات بیشتر در مورد انتظارات کاربر در مقایسه با رفتار سیستم و نحوه حفظ بهترین حالت داده‌های وضعیت رابط کاربری پیچیده در فعالیت‌های آغاز شده توسط سیستم و مرگ فرآیند، به ذخیره حالت‌های رابط کاربری مراجعه کنید.

در این بخش توضیح می‌دهیم که وضعیت نمونه چیست و چگونه می‌توان متد onSaveInstance() که یک فراخوانی در خود اکتیویتی است، پیاده‌سازی کرد. اگر داده‌های رابط کاربری شما سبک هستند، می‌توانید از onSaveInstance() به تنهایی برای حفظ وضعیت رابط کاربری در تغییرات پیکربندی و مرگ فرآیند آغاز شده توسط سیستم استفاده کنید. اما از آنجایی که onSaveInstance() متحمل هزینه‌های سریال‌سازی/درسیال‌سازی می‌شود، در بیشتر موارد از ViewModel و onSaveInstance() استفاده می‌کنید، همانطور که در حالت‌های Save UI مشخص شده است.

توجه: برای کسب اطلاعات بیشتر در مورد تغییرات پیکربندی، نحوه محدود کردن فعالیت‌های تفریحی در صورت نیاز، و نحوه واکنش به این تغییرات پیکربندی از سیستم View و Jetpack Compose، صفحه تغییرات پیکربندی Handle را بررسی کنید.

حالت نمونه

چند سناریو وجود دارد که در آن فعالیت شما به دلیل رفتار نرمال برنامه از بین می رود، مانند زمانی که کاربر دکمه Back را فشار می دهد یا فعالیت شما با فراخوانی متد finish() سیگنال تخریب خود را می دهد.

وقتی فعالیت شما از بین می رود زیرا کاربر Back را فشار می دهد یا فعالیت خود به پایان می رسد، مفهوم سیستم و کاربر از آن نمونه Activity برای همیشه از بین می رود. در این سناریوها، انتظارات کاربر با رفتار سیستم مطابقت دارد و شما هیچ کار اضافی برای انجام ندارید.

با این حال، اگر سیستم فعالیت را به دلیل محدودیت‌های سیستم (مانند تغییر پیکربندی یا فشار حافظه) از بین ببرد، اگرچه نمونه Activity واقعی از بین رفته است، سیستم به یاد می‌آورد که وجود داشته است. اگر کاربر بخواهد به فعالیت برگردد، سیستم نمونه جدیدی از آن فعالیت را با استفاده از مجموعه ای از داده های ذخیره شده ایجاد می کند که وضعیت فعالیت را در هنگام نابودی توصیف می کند.

داده های ذخیره شده ای که سیستم برای بازیابی حالت قبلی استفاده می کند، حالت نمونه نامیده می شود. این مجموعه ای از جفت های کلید-مقدار ذخیره شده در یک شی Bundle است. به طور پیش‌فرض، سیستم از حالت نمونه Bundle برای ذخیره اطلاعات درباره هر شی View در طرح‌بندی فعالیت شما، مانند مقدار متن وارد شده در ویجت EditText استفاده می‌کند.

بنابراین، اگر نمونه اکتیویتی شما از بین برود و دوباره ایجاد شود، بدون نیاز به کد مورد نیاز، وضعیت طرح به حالت قبلی خود باز می گردد. با این حال، فعالیت شما ممکن است اطلاعات وضعیت بیشتری داشته باشد که می‌خواهید بازیابی کنید، مانند متغیرهای عضوی که پیشرفت کاربر را در فعالیت دنبال می‌کنند.

توجه: برای اینکه سیستم اندروید وضعیت نماهای موجود در فعالیت شما را بازیابی کند، هر نما باید یک شناسه منحصر به فرد داشته باشد که توسط ویژگی android:id ارائه شده است.

یک شی Bundle برای حفظ بیش از مقدار کمی داده مناسب نیست، زیرا به سریال سازی در رشته اصلی نیاز دارد و حافظه فرآیند سیستم را مصرف می کند. برای حفظ بیش از مقدار بسیار کمی داده، یک رویکرد ترکیبی برای حفظ داده ها، با استفاده از ذخیره سازی محلی دائمی، متد onSaveInstanceState() و کلاس ViewModel ، همانطور که در حالت های Save UI مشخص شده است، در نظر بگیرید.

حالت رابط کاربری ساده و سبک را با استفاده از onSaveInstanceState() ذخیره کنید

هنگامی که فعالیت شما شروع به توقف می کند، سیستم متد onSaveInstanceState() را فراخوانی می کند تا فعالیت شما بتواند اطلاعات حالت را در یک بسته حالت نمونه ذخیره کند. اجرای پیش‌فرض این روش اطلاعات گذرا درباره وضعیت سلسله‌مراتب نمای فعالیت، مانند متن موجود در ویجت EditText یا موقعیت اسکرول ویجت ListView را ذخیره می‌کند.

برای ذخیره اطلاعات اضافی حالت نمونه برای اکتیویتی خود، onSaveInstanceState() را لغو کنید و جفت های کلید-مقدار را به شی Bundle اضافه کنید که در صورت نابودی غیرمنتظره اکتیویتی شما ذخیره می شود. هنگامی که onSaveInstanceState() را نادیده می گیرید، اگر می خواهید اجرای پیش فرض وضعیت سلسله مراتب view را ذخیره کند، باید اجرای superclass را فراخوانی کنید. این در مثال زیر نشان داده شده است:

کاتلین

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"
}

جاوا

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);
}

توجه: هنگامی که کاربر به طور صریح فعالیت را می بندد یا در موارد دیگر هنگامی که finish() فراخوانی می شود onSaveInstanceState() فراخوانی نمی شود.

برای ذخیره داده های پایدار، مانند تنظیمات برگزیده کاربر یا داده های یک پایگاه داده، زمانی که فعالیت شما در پیش زمینه است، از فرصت های مناسب استفاده کنید. اگر چنین فرصتی پیش نیامد، داده های پایدار را در طول متد onStop() ذخیره کنید.

بازیابی وضعیت رابط کاربری فعالیت با استفاده از حالت نمونه ذخیره شده

وقتی اکتیویتی شما پس از اینکه قبلاً از بین رفته است دوباره ایجاد می شود، می توانید حالت نمونه ذخیره شده خود را از Bundle که سیستم به فعالیت شما ارسال می کند، بازیابی کنید. هر دو متد onCreate() و onRestoreInstanceState() همان Bundle دریافت می کنند که حاوی اطلاعات حالت نمونه است.

از آنجایی که متد onCreate() فراخوانی می‌شود که آیا سیستم نمونه جدیدی از فعالیت شما را ایجاد می‌کند یا یک نمونه قبلی را دوباره ایجاد می‌کند، قبل از اینکه بخواهید آن را بخوانید باید بررسی کنید که آیا Bundle حالت تهی است یا خیر. اگر تهی باشد، سیستم در حال ایجاد یک نمونه جدید از فعالیت است، به جای بازیابی نمونه قبلی که از بین رفته است.

قطعه کد زیر نشان می دهد که چگونه می توانید برخی از داده های حالت را در onCreate() بازیابی کنید:

کاتلین

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.
    }
    // ...
}

جاوا

@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 نیست.

کاتلین

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)
    }
}

جاوا

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() را فراخوانی کنید تا اجرای پیش فرض بتواند وضعیت سلسله مراتب view را بازیابی کند.

پیمایش بین فعالیت ها

احتمالاً یک برنامه در طول عمر برنامه بارها وارد یک فعالیت شده و از آن خارج می شود، مانند زمانی که کاربر روی دکمه برگشت دستگاه ضربه می زند یا فعالیت فعالیت دیگری را راه اندازی می کند.

این بخش موضوعاتی را پوشش می دهد که برای اجرای موفقیت آمیز انتقال فعالیت باید بدانید. این موضوعات شامل شروع یک فعالیت از یک فعالیت دیگر، ذخیره وضعیت فعالیت و بازیابی وضعیت فعالیت است.

شروع یک فعالیت از فعالیت دیگر

یک فعالیت اغلب نیاز به شروع فعالیت دیگری در نقطه ای دارد. این نیاز، برای مثال، زمانی ایجاد می‌شود که یک برنامه باید از صفحه فعلی به صفحه جدید منتقل شود.

بسته به اینکه آیا اکتیویتی شما نتیجه فعالیت جدیدی را که در شرف شروع است می‌خواهد یا نه، فعالیت جدید را با استفاده از متد startActivity() یا متد startActivityForResult() شروع می‌کنید. در هر صورت، شما در یک شی Intent عبور می کنید.

شی Intent یا فعالیت دقیقی را که می خواهید شروع کنید مشخص می کند یا نوع عملی را که می خواهید انجام دهید را توصیف می کند. سیستم فعالیت مناسب را برای شما انتخاب می کند که حتی می تواند از یک برنامه متفاوت باشد. یک شی Intent همچنین می تواند مقادیر کمی از داده ها را برای فعالیتی که شروع شده است حمل کند. برای اطلاعات بیشتر در مورد کلاس Intent ، Intent و Intent Filters را ببینید.

startActivity()

اگر فعالیت تازه شروع شده نیازی به بازگرداندن نتیجه نداشته باشد، اکتیویتی فعلی می تواند با فراخوانی متد startActivity() آن را شروع کند.

هنگامی که در برنامه خود کار می کنید، اغلب باید به سادگی یک فعالیت شناخته شده را راه اندازی کنید. برای مثال، قطعه کد زیر نحوه راه‌اندازی فعالیتی به نام SignInActivity را نشان می‌دهد.

کاتلین

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

جاوا

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

همچنین ممکن است برنامه شما بخواهد با استفاده از داده‌های فعالیت شما، اقداماتی مانند ارسال ایمیل، پیام متنی یا به‌روزرسانی وضعیت را انجام دهد. در این حالت، برنامه شما ممکن است فعالیت‌های خاص خود را برای انجام چنین اقداماتی نداشته باشد، بنابراین می‌توانید در عوض از فعالیت‌های ارائه‌شده توسط برنامه‌های دیگر روی دستگاه استفاده کنید، که می‌توانند این اقدامات را برای شما انجام دهند.

اینجاست که مقاصد واقعاً ارزشمند هستند. می‌توانید یک intent ایجاد کنید که عملکردی را که می‌خواهید انجام دهید را توصیف می‌کند و سیستم فعالیت مناسب را از برنامه دیگری راه‌اندازی می‌کند. اگر چندین فعالیت وجود داشته باشد که بتواند هدف را مدیریت کند، کاربر می تواند انتخاب کند که از کدام یک استفاده کند. به عنوان مثال، اگر می خواهید به کاربر اجازه دهید یک پیام ایمیل ارسال کند، می توانید هدف زیر را ایجاد کنید:

کاتلین

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

جاوا

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

EXTRA_EMAIL اضافی اضافه شده به intent یک آرایه رشته ای از آدرس های ایمیل است که ایمیل باید به آن ارسال شود. هنگامی که یک برنامه ایمیل به این هدف پاسخ می دهد، آرایه رشته ای ارائه شده در قسمت اضافی را می خواند و آدرس ها را در قسمت "to" فرم ترکیب ایمیل قرار می دهد. در این شرایط، فعالیت اپلیکیشن ایمیل شروع می شود و پس از اتمام کار کاربر، فعالیت شما از سر گرفته می شود.

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 دریافت می‌کند.

کاتلین

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
    }
}

جاوا

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));
             }
         }
     }
 }

هماهنگی فعالیت ها

هنگامی که یک فعالیت فعالیت دیگری را شروع می کند، هر دوی آنها تغییر چرخه زندگی را تجربه می کنند. فعالیت اول متوقف می شود و وارد حالت Paused یا Stopped می شود، در حالی که فعالیت دیگر ایجاد می شود. در صورتی که این فعالیت‌ها داده‌های ذخیره‌شده در دیسک یا مکان‌های دیگر را به اشتراک بگذارند، درک این نکته مهم است که فعالیت اول قبل از ایجاد دومین فعالیت کاملاً متوقف نمی‌شود. بلکه روند شروع دومی با روند توقف اولی همپوشانی دارد.

ترتیب تماس‌های چرخه حیات به‌خوبی تعریف شده است، به‌ویژه زمانی که این دو فعالیت در یک فرآیند هستند - به عبارت دیگر، یک برنامه - و یکی در حال شروع دیگری است. ترتیب عملیاتی که هنگام شروع فعالیت A، فعالیت B انجام می شود در اینجا آمده است:

  1. متد onPause() Activity A اجرا می شود.
  2. متدهای onCreate() ، onStart() و onResume() در اکتیویتی B به ترتیب اجرا می شوند. فعالیت B اکنون تمرکز کاربر را دارد.
  3. اگر فعالیت A دیگر روی صفحه قابل مشاهده نباشد، متد onStop() آن اجرا می شود.

این توالی تماس های چرخه حیات به شما امکان می دهد انتقال اطلاعات از یک فعالیت به فعالیت دیگر را مدیریت کنید.