درک چرخه حیات اکتیویتی

همانطور که کاربر از برنامه شما خارج ، و به برنامه شما بازمی گردد ، نمونه های Activity در برنامه شما در حال انتقال ازحالت های مختلف در چرخه حیات خود هستند. کلاس Activity تعدادی کالبک ارائه می دهد که به activity این امکان را می دهد تا بفهمد حالت تغییر کرده است: (اینکه سیستم activityرا ایجاد ، متوقف (stopping) یا از سر می گیرد (resuming ) یا فرایندی را که activity در آن قرار دارد از بین می برد.)در متد های کالبک چرخه حیات می توانید نحوه عملکرد خود را هنگام ترک کاربر و ورود مجدد آن به activity ، تعریف کنید. به عنوان مثال ، اگر در حال ساخت یک ویدیو پلیر استریم هستید ، ممکن است وقتی کاربر به برنامه دیگری سوییچ می کند ، ویدیو را مکث کرده و اتصال شبکه را قطع کنید. وقتی کاربر برگشت ، می توانید دوباره به شبکه متصل شوید و به کاربر اجازه دهید فیلم را از همان نقطه از سر بگیرد. به عبارت دیگر ، هر کالبک به شما امکان می دهد کار خاصی را انجام دهید که متناسب با تغییر وضعیت داده شده باشد. انجام کار مناسب در زمان مناسب و مدیریت صحیح انتقال (transitions )، برنامه شما را قدرتمندتر و کارآمدتر می کند. به عنوان مثال ، اجرای خوب کالبک چرخه حیات می تواند اطمینان حاصل کند که برنامه شما از موارد زیر جلوگیری می کند:اگر کاربر هنگام استفاده از برنامه شما تماس تلفنی دریافت کند یا به برنامه دیگری سوییچ کند ، کرش میکندمصرف منابع ارزشمند سیستم وقتی کاربر فعالانه از آن استفاده نمی کند.اگر کاربر از برنامه شما خارج شود و بعداً به آن بازگردد ، پیشرفت کاربر را از دست دهید.کرش یا از دست دادن پیشرفت کاربر هنگام چرخش صفحه نمایش بین جهت افقی و عمودی.این داکیومنت چرخه حیات اکتیویتی را با جزئیات توضیح می دهد. این داکیومنت با توصیف الگوی چرخه حیات آغاز می شود. بعد ، هر یک ازکالبک ها را توضیح می دهد: چه اتفاقی درداخل میافتد زمانی که انها اجرا می شوند ، و آنچه را که باید در طی آنها باید پیاده کنید . سپس به طور خلاصه رابطه بین وضعیت اکتیویتی و آسیب پذیری یک فرایند برای کشته شدن توسط سیستم را معرفی می کند. در آخر ، چندین موضوع مربوط به انتقال بین حالتهای اکتیویتی مورد بحث قرار می گیرد.برای کسب اطلاعات در مورد هندل کردن چرخه های حیات ، از جمله راهنمایی در مورد بهترین روش ها ، به هندل کردن چرخه های حیات باLifecycle-Aware Components وSaving UI States مراجعه کنید. برای یادگیری نحوه تولید معماری یک برنامه قوی و با کیفیت با استفاده از اکتیویتی هایی در ترکیب با کامپاننت های معماری ، به راهنمای معماری برنامه مراجعه کنید.Activity-lifecycle concepts مفاهیم چرخه حیات اکتیویتی برای پیمایش در انتقال بین مراحل چرخه حیات اکتیویتی ، کلاس Activity یک مجموعه اصلی متشکل از شش کال بک را ارائه می دهد:onCreate(), on Start, on Resume, on Pause, on Stop, و onDestroy()با ورود اکتیویتی به وضعیت جدید ، این سیستم هر یک از این کال بک ها را فراخوانی می کند.شکل 1 نمایش تصویری این الگو را نشان می دهدهنگامی که کاربر شروع به ترک activity می کند ، سیستم متد هایی را برای از بین بردن activity فراخوانی می کند. در برخی موارد ، این برچیدن فقط جزئی است. این activity همچنان در حافظه باقی مانده است (مانند زمانی که کاربر به برنامه دیگری سوییچ می کند) و هنوز هم می تواند به پیش زمینه بازگردد. در صورت بازگشت کاربر به آن activity، activity از همان جایی که کاربر متوقف شده از سر گرفته می شود. به استثنای چند مورد ، برنامه ها هنگام استارت اکتیویتی در پس زمینه محدودیدت دارند.https://developer.android.com/guide/components/activities/background-startsاحتمال سیستم برای از بین بردن یک فرآیند معین - همراه با اکتیویتی های موجود در آن - به وضعیت اکتیویتی در آن زمان بستگی دارد.Activity state and ejection from memory ، اطلاعات بیشتری در مورد رابطه بین وضعیت و آسیب پذیری در برابر اخراج فراهم می کند.بسته به پیچیدگی اکتیویتی شما ، احتمالاً نیازی به پیاده سازی همه متد های های چرخه حیات ندارید. با این حال ، مهم این است که شما هر یک از انها را بفهمید و مواردی را که باعث میشود برنامه شما مطابق انتظار کاربران عمل می کند ، را پیاده سازی کنید.بخش بعدی این مستند جزئیاتی را در مورد کال بک هایی ارائه می دهد که برای مدیریت انتقال بین حالتها استفاده می کنید.Lifecycle callbacksدر این بخش اطلاعات مفهومی و پیاده سازی در مورد متد های کالبک استفاده شده در طول چرخه حیات اکتیویتی ارائه می شود.بعضی از اکشن ها مانند فراخوانی setContentView () ، متعلق به خود چرخه حیات اکتیویتی است. با این حال ،کدی که اکشن یک کامپاننت وابسته را اجرا می کند باید در خود کامپاننت قرار گیرد. برای دستیابی به این هدف ، باید کامپاننت وابسته را از چرخه حیات آگاه کنید. برای یادگیری نحوه آگاهی از کامپاننت های وابسته به چرخه حیات به بخش مدیریت چرخه های حیات با کامپاننت آگاه از چرخه زندگی مراجعه کنید.https://developer.android.com/topic/libraries/architecture/lifecycleonCreate()شما باید این کالبک را ، زمانی که سیستم برای اولین بار اکتیویتی را میسازد اجرا کنید. با ایجاد اکتیویتی، اکتیویتی وارد حالت Created می شود. در متد () onCreate ، شما منطق اصلی راه اندازی برنامه را اجرا می کنید که باید فقط یک بار در کل حیات اکتیویتی رخ دهد. به عنوان مثال ،شما با اجرای onCreate () ممکن است داده ها را به لیست ها متصل کنید ، اکتیویتی را با یک ViewModel مرتبط کنید و برخی متغیرهای در اسکوپ کلاس را نمونه سازی کند. این متد پارامتر SaveInstanceState را دریافت می کند ، که یک شی Bundle است و حاوی حالت ذخیره شده قبلی اکتیویتی است. اگر اکتیویتی قبلاً هرگز وجود نداشته باشد ، مقدار Bundle نال است.اگر یک کامپاننت آگاه از چرخه حیات داشته باشید که با چرخه حیات اکتیویتی شما در ارتباط باشد ، رویداد ON_CREATE را دریافت می کند. متد annotated شده با @OnLifecycleEvent فراخوانی می شود بنابراین component آگاه از چرخه حیات شما می تواند هر کد راه اندازی مورد نیاز برای حالت Create شده را انجام دهد.در مثال زیر متد () onCreate تنظیمات اساسی اکتیویتی را نشان می دهد ، مانند اعلام رابط کاربر (تعریف شده در یک فایل طرح XML) ، تعریف متغیرهای member و پیکربندی برخی از رابط کاربری. در این مثال ، فایل Layout XML با پاس دادن ID ریسورس فایل R.layout.main_activity به setContentView () مشخص می شود.TextView textView; // some transient state for the activity instance String gameState; @Override public void onCreate(Bundle savedInstanceState) { // call the super class onCreate to complete the creation of activity like // the view hierarchy super.onCreate(savedInstanceState); // recovering the instance state if (savedInstanceState != null) { gameState = savedInstanceState.getString(GAME_STATE_KEY); } // set the user interface layout for this activity // the layout file is defined in the project res/layout/main_activity.xml file setContentView(R.layout.main_activity); // initialize member TextView so we can manipulate it later textView = (TextView) findViewById(R.id.text_view); } // This callback is called only when there is a saved instance that is previously saved by using // onSaveInstanceState(). We restore some state in onCreate(), while we can optionally restore // other state here, possibly usable after () 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 may 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 جدیدی را در کد اکتیویتی خود بسازید و با قرار دادن Views جدید در یک ViewGroup یک سلسله مراتب ویو ایجاد کنید. سپس با پاس دادن ریشه ViewGroup به setContentView () از آن لی اوت استفاده می کنید. برای کسب اطلاعات بیشتر در مورد ایجاد یک رابط کاربر ، به اسناد رابط کاربر مراجعه کنید.https://developer.android.com/guide/topics/uiاکتیویتی شما در حالت Created باقی نمی ماند . بعد از اینکه متد onCreate () به پایان رسید ، فعالیت وارد حالت Started می شود و سیستم متناوباً متدهای ()on Start و () on Resumeرا فراخوانی می کند. بخش بعدی کالبک ()on Start را توضیح می دهد.()on Startوقتی اکتیویتی وارد حالت Started می شود ، سیستم این کالبک را فراخوانی می کند. کالبک () on Startاکتیویتی را برای کاربر قابل مشاهده می کند ، زیرا برنامه آماده می شود تا اکتیوتی وارد پیش زمینه شود و تعاملی شود. به عنوان مثال ، این متد جایی است که برنامه کدی را که UI را نگه داری می کند مقدار اولیه می دهد.وقتی اکتیوتی به حالت آغاز شده می رود ، هر کامپاننت که از چرخه حیات آگاه باشد و به چرخه حیات اکتیویتی مرتبط باشد ، رویداد ON_START را دریافت می کند.روش ()on Start خیلی سریع تکمیل می شود و مانند حالت Created ، اکتیویتی در حالت Started باقی نمی ماند. پس از پایان این کالبک ، اکتیویتی وارد حالت Resume می شود و سیستم متد () Resume را فراخوانی می کند.()on Resume.هنگامی که اکتیوتی وارد حالت Resume می شود به پیش زمینه امده است و سپس سیستم کالبک () on Resume را فراخوانی می کند. این وضعیتی است که برنامه در آن با کاربر تعامل دارد. برنامه تا زمانی که اتفاقی بخواهد تمرکز را از برنامه دور کند ، در این حالت باقی می ماند. چنین رویدادی ممکن است مثلاً دریافت تماس تلفنی ، رفتن کاربر به اکتیویتی دیگری یا خاموش شدن صفحه دستگاه باشد.وقتی اکتیویتی به حالت resumed انتقال داده میشود ، هر یک از کامپاننت آگاه از چرخه حیات که به چرخه حیات اکتیویتی مرتبط باشد ، رویداد ON_RESUME را دریافت می کند. اینجاست که اجزای چرخه حیات می توانند هر عملکردی را که لازم است اجرا شود در حالی که کامپاننت قابل مشاهده است و در پیش زمینه قرار دارد ، مانند شروع پیش نمایش دوربین.هنگامی که یک وقفه قطع رخ میدهد ، اکتیویتی وارد حالت Paused می شود و سیستم کالبک() on Pauseرا فراخوانی می کند.اگر اکتیویتی از حالت Paused به حالت Resume برگردد ، سیستم بار دیگر متد () Resume را فراخوانی می کند. به همین دلیل ، شما باید () on Resume را پیاده سازی کنید تا کامپاننت هایی را که در حین on Pause آزاد می کنید () مقدار دهی اولیه کنید و سایر تنظیمات اولیه را که باید با هر بار ورود اکتیوتی به حالت Resume انجام شود ، انجام دهید.در اینجا مثالی از یک کامپاننت آگاه از چرخه زندگی وجود دارد که با دریافت رویداد ON_RESUME به دوربین دسترسی پیدا می کند:public class CameraComponent implements LifecycleObserver { ... @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) public void initializeCamera() { if (camera == null) { getCamera(); } } ... }هنگامی که LifecycleObserver رویداد ON_RESUME را دریافت کرد ، کد بالا دوربین را مقداردهی اولیه می کند. اما در حالت چند پنجره ای ، اکتیویتی شما حتی در حالت Paused نیز ممکن است کاملاً قابل مشاهده باشد. به عنوان مثال ، وقتی کاربر در حالت چند پنجره ای است و روی پنجره دیگری که شامل اکتیویتی شما نیست ضربه می زند ، اکتیویتی شما به حالت Paused منتقل می شود. اگر می خواهید دوربین فقط هنگام ازResumed برنامه فعال باشد (در پیش زمینه (foreground) قابل مشاهده و فعال باشد) ، پس از رویداد ON_RESUME که در بالا نشان داده شد ، دوربین را اینشیالایز کنید. اگر می خواهید در حالی که فعالیت Paused است اما قابل مشاهده است ، دوربین را فعال نگه دارید (به عنوان مثال در حالت چند پنجره ای) ، در عوض باید پس از رویداد ON_START دوربین را اینشیالایز کنید. با این حال ، توجه داشته باشید که داشتن فعال بودن دوربین در حین Pause بودن اکتیویتی شما ممکن است دسترسی به دوربین را به یک برنامه دیگرکه درحالت Resumed در حالت چند پنجره منع کند. گاهی اوقات ممکن است لازم باشد که دوربین در حین Pause بودن ، فعال باشد. اگر این کار را انجام دهید ممکن است تجربه کلی کاربر را تنزل دهید. با دقت فکر کنید که در کدام چرخه ای حیات کنترل منابع سیستم مشترک در پنجره چند منظوره مناسب تر است. برای کسب اطلاعات بیشتر در مورد پشتیبانی از حالت چند پنجره ، به پشتیبانی چند پنجره مراجعه کنید.https://developer.android.com/guide/topics/ui/multi-windowصرف نظر از اینکه در کدام رویداد ایجاد شده برای انجام عملیات مقداردهی اولیه انتخاب می کنید ، حتماً از رویداد مربوط به چرخه حیات برای آزاد کردن منبع استفاده کنید. اگر پس از رویداد ON_START چیزی را مقداردهی اولیه کردید ، پس از رویداد ON_STOP آن را آزاد یا خاتمه دهید. اگر پس از رویداد ON_RESUME مقداردهی اولیه کردید ، پس از رویداد ON_PAUSE آن را آزاد کنید.توجه داشته باشید ، قطعه کد بالا کد initialization دوربین را در یک کامپاننت آگاه از چرخه زندگی قرار می دهد.شما میتوانید به جای این کار کد را مستقیماً در کالبک های چرخه حیات اکتیویتی مانند () و () قرار دهید اما این توصیه نمی شود. افزودن این منطق به یک کامپاننت مستقل و آگاه از چرخه زندگی به شما امکان می دهد بدون نیاز به تکثیر کد ، ازکامپاننت در چندین فعالیت استفاده مجدد کنید. برای یادگیری نحوه ایجاد یک کامپاننت از چرخه زندگی ، به مدیریت چرخه های زندگی با اجزای آگاه از چرخه زندگی مراجعه کنید.https://developer.android.com/topic/libraries/architecture/lifecycleon Pause()سیستم این متد را به عنوان اولین نشانه ای از ترک اکتیویتی توسط کاربر فراخوانی میکند (البته این همیشه به معنای از بین رفتن اکتیویتی نیست). این نشان می دهد که اکتیویتی دیگر در پیش زمینه (foreground ) نیست (اگر کاربر در حالت چند پنجره ای است هنوز هم ممکن است قابل مشاهده باشد). از متد on Pause () برای مکث یا تنظیم عملیاتی که نباید ادامه داشته باشند (یا باید به صورت متوسط ادامه داشته باشند) در حالی که اکتویتی در حالت Paused است استفاده کنید و انتظار دارید که به زودی از سر گرفته (resume ) شود. دلایل مختلفی وجود دارد که ممکن است activity وارد این حالت شود. مثلا:همانطور که در بخش on Resume () توضیح داده شده است ، برخی از رویدادها اجرای برنامه را قطع می کنند. این شایع ترین مورد است.در Android 7.0 (API سطح 24) یا بالاتر ، چندین برنامه در حالت چند پنجره ای اجرا می شوند. از آنجا که فقط یکی از برنامه ها (ویندوز) در هر زمان تمرکز دارد ، سیستم همه برنامه های دیگر را pauses می کند.یک اکتیویتی نیمه شفاف (semi-transparent) جدید (مانند یک dialog) باز می شود. تا زمانی که اکتیویتی هنوز تا حدی قابل مشاهده است اما در focus نیست ، در حالت paused باقی می ماند.وقتی اکتیویتی به حالتpauses منتقل شود ، هر یک از کامپاننت های آگاه از چرخه حیات که به چرخه حیات اکتیویتی مرتبط است ، رویداد ON_PAUSE را دریافت می کند. اینجاست که کامپاننت چرخه حیات می توانند هر عملکردی را که نیازی به اجرا ندارد زمانی که component در پیش زمینه نیست متوقف کنند ، مانند توقف(stopping ) پیش نمایش دوربینهمچنین می توانید از متد on Pause () برای آزاد کردن منابع سیستم ، هندل کردن حسگرها (مانند GPS) یا هر منبعی که ممکن است در باتری تاثیر داشته باشد در حالی که اکتیویتی شما paused است و کاربر به آنها نیازی ندارد ، استفاده کنید. با این وجود ، همانطور که در قسمت بالا در () on Resume ذکر شد ، اگر در حالت چند پنجره ای باشد ، اکتیویتی متوقف شده ممکن است کاملاً قابل مشاهده باشد. به همین دلیل ، باید در استفاده از on Stop () به جای on Pause() استفاده کنید تا منابع و عملیات مربوط به UI را به طور کامل آزاد کنید واز حالت چند پنجره بهتر پشتیبانی کند.مثال زیر از LifecycleObserver که به رویداد ON_PAUSE واکنش نشان می دهد ، نمونه مقابل رویداد ON_RESUME در بالا است و دوربینی را که پس از دریافت رویداد ON_RESUME مقدار دهی اولیه شده بود ،را آزاد می کند:public class JavaCameraComponent implements LifecycleObserver { ... @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) public void releaseCamera() { if (camera != null) { camera.release(); camera = null; } } ... }اجرای ()on Pause بسیار کوتاه است و لزوماً وقت کافی برای انجام عملیات ذخیره را ندارد. به همین دلیل ، برای ذخیره برنامه یا داده کاربر ، برقراری تماس شبکه یا انجام تراکنش های پایگاه داده ، نباید از ()on Pause استفاده کنید. چنین کارهایی ممکن است قبل از اتمام متد کامل نشود. درعوض ، شما باید در حین عملیات خاموش کردن بار سنگین را انجام دهید. برای کسب اطلاعات بیشتر در مورد عملیات مناسب برای انجام در هنگام () on Stop، به () on Stop مراجعه کنید.https://developer.android.com/reference/android/app/Activity#()برای کسب اطلاعات بیشتر در مورد ذخیره اطلاعات ، به ذخیره و بازیابی وضعیت اکتیویتی مراجعه کنیدhttps://developer.android.com/guide/components/activities/activity-lifecycle#sarasتکمیل متد ()on Pause به معنی خروج اکتیوتی از حالت نیست. بلکه اکتیویتی در این حالت باقی می ماند تا زمانی که اکتیویتی دوباره از سر گرفته شود (resumes ) یا برای کاربر کاملاً نامرئی (invisible ) شود. اگر اکتیویتی از سر گرفته شود ، سیستم مجدداً کالبک () on Resume را فراخوانی می کند. اگر اکتیویتی از حالت Paused به حالت Resume برگردد ، سیستم نمونه Activity را در حافظه نگه می دارد ، و آن نمونه را هنگام فراخوانی سیستم رویResume () دوباره فراخوانی می کند. در این سناریو ، نیازی نیست که مجدداً components ایجاد شده در طی هر یک از متد های کالبک که منجر به حالت Resume میشوند را دوباره مقدار دهی اولیه کنید. اگر اکتیویتی کاملاً نامرئی شود ، سیستم STOP ()فراخوانی میکند در بخش بعدی ، کالبک () STOP مورد بحث قرار می گیرد.on Stop ادامه دارد :)