Android Kotlin Fundamentals 04.1: چرخه های زندگی و ورود به سیستم

این کد لبه بخشی از دوره آموزشی Android Kotlin Fundamentals است. اگر به ترتیب روی کدها کار کنید، بیشترین ارزش را از این دوره خواهید گرفت. همه کدهای دوره در صفحه فرود کد لبه های کدهای Android Kotlin Fundamentals فهرست شده اند.

مقدمه

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

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

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

آنچه از قبل باید بدانید

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

چیزی که یاد خواهید گرفت

  • نحوه چاپ اطلاعات ورود به سیستم در Logcat (که گاهی به آن کنسول اندروید یا مانیتور اندروید گفته می شود).
  • اصول اولیه چرخه‌های حیات Activity و Fragment و تماس‌هایی که هنگام حرکت فعالیت بین حالت‌ها فراخوانی می‌شوند.
  • نحوه نادیده گرفتن روش‌های برگشت به تماس چرخه حیات برای انجام عملیات در زمان‌های مختلف در چرخه حیات فعالیت.
  • چگونه از کتابخانه Timber برای ورود به برنامه خود استفاده کنید.

کاری که خواهی کرد

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

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

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

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

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

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

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

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

مرحله 1: روش onCreate() را بررسی کرده و لاگ اضافه کنید

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

یک راه ساده برای انجام این کار استفاده از API Logging Android است. ورود به سیستم به شما امکان می‌دهد در حین اجرای برنامه، پیام‌های کوتاهی را برای کنسول بنویسید، و می‌توانید از آن برای نشان دادن زمانی که تماس‌های مختلف فعال می‌شوند، استفاده کنید.

  1. برنامه استارتر DessertClicker را دانلود کرده و در اندروید استودیو باز کنید.
  2. برنامه را کامپایل و اجرا کنید و چند بار روی عکس دسر ضربه بزنید. توجه داشته باشید که ارزش دسرهای فروخته شده و کل مبلغ دلار چگونه تغییر می کند.
  3. MainActivity.kt باز کنید و onCreate() را برای این اکتیویتی بررسی کنید
override fun onCreate(savedInstanceState: Bundle?) {
...
}

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

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

  1. در onCreate() درست بعد از فراخوانی super.onCreate() خط زیر را اضافه کنید. در صورت لزوم کلاس Log را وارد کنید. ( Alt+Enter یا Option+Enter را در Mac فشار دهید و Import را انتخاب کنید.)
Log.i("MainActivity", "onCreate Called")

کلاس Log پیام هایی را برای Logcat می نویسد. این دستور سه بخش دارد:

  • شدت پیام لاگ، یعنی اینکه پیام چقدر مهم است. در این حالت، Log.i() یک پیام اطلاعاتی می نویسد. متدهای دیگر در کلاس Log عبارتند از Log.e() برای خطاها یا Log.w() برای هشدارها.
  • تگ گزارش، در این مورد "MainActivity" . تگ رشته‌ای است که به شما امکان می‌دهد پیام‌های گزارش خود را راحت‌تر در Logcat پیدا کنید. تگ معمولاً نام کلاس است.
  • پیام گزارش واقعی، یک رشته کوتاه، که در این مورد "onCreate called" است.
  1. برنامه DessertClicker را کامپایل و اجرا کنید. وقتی روی دسر ضربه می‌زنید، هیچ تفاوت رفتاری در برنامه مشاهده نمی‌کنید. در اندروید استودیو، در پایین صفحه، روی زبانه Logcat کلیک کنید.



    Logcat کنسولی برای ثبت پیام ها است. پیام‌هایی از Android درباره برنامه شما در اینجا ظاهر می‌شوند، از جمله پیام‌هایی که به صراحت با Log.i() یا سایر روش‌های کلاس Log به گزارش ارسال می‌کنید.
  2. در قسمت Logcat ، I/MainActivity را در قسمت جستجو تایپ کنید.


    Logcat می تواند حاوی پیام های زیادی باشد که بیشتر آنها برای شما مفید نیستند. شما می توانید ورودی های Logcat را به طرق مختلف فیلتر کنید، اما جستجو ساده ترین است. از آنجایی که از MainActivity به عنوان تگ گزارش در کد خود استفاده کرده اید، می توانید از آن تگ برای فیلتر کردن گزارش استفاده کنید. افزودن I/ در ابتدا به این معنی است که این یک پیام اطلاعاتی است که توسط Log.i() ایجاد شده است.

    پیام گزارش شما شامل تاریخ و زمان، نام بسته ( com.example.android.dessertclicker )، برچسب گزارش شما (با I/ در شروع)، و پیام واقعی است. از آنجا که این پیام در گزارش ظاهر می شود، می دانید که onCreate() اجرا شده است.

مرحله 2: متد onStart() را پیاده سازی کنید

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

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

  1. در Android Studio، با باز بودن MainActivity.kt ، Code > Override Methods را انتخاب کنید یا Control+o را فشار دهید. یک گفتگو با لیست بزرگی از تمام روش هایی که می توانید در این کلاس لغو کنید ظاهر می شود.
  2. برای جستجوی روش مناسب وارد onStart شوید. برای پیمایش به مورد منطبق بعدی، از فلش رو به پایین استفاده کنید. onStart() را از لیست انتخاب کنید و برای درج کد نادیده گرفته شده دیگ بخار روی OK کلیک کنید. کد به شکل زیر است:
override fun onStart() {
   super.onStart()
}
  1. در متد onStart() یک پیام log اضافه کنید:
override fun onStart() {
   super.onStart()

   Log.i("MainActivity", "onStart Called")
}
  1. برنامه DessertClicker را کامپایل و اجرا کنید و پنجره Logcat را باز کنید. برای فیلتر کردن گزارش، I/MainActivity را در قسمت جستجو تایپ کنید. توجه داشته باشید که هر دو onCreate() و onStart() یکی پس از دیگری فراخوانی شده اند و فعالیت شما روی صفحه قابل مشاهده است.
  2. دکمه صفحه اصلی را در دستگاه فشار دهید و سپس از صفحه اخیر برای بازگشت به فعالیت استفاده کنید. توجه داشته باشید که اکتیویتی از همان جایی که متوقف شد، با همان مقادیر از سر گرفته می‌شود و onStart() برای بار دوم در Logcat ثبت می‌شود. همچنین توجه داشته باشید که onCreate() معمولاً دوباره فراخوانی نمی شود.

در این کار، برنامه خود را طوری تغییر می‌دهید که از یک کتابخانه گزارش‌گیری معروف به نام Timber استفاده کند. Timber دارای چندین مزیت نسبت به کلاس Android Log داخلی است. به طور خاص، کتابخانه Timber :

  • بر اساس نام کلاس تگ log را برای شما ایجاد می کند.
  • به شما کمک می‌کند تا از نمایش گزارش‌ها در نسخه منتشرشده برنامه Android خود اجتناب کنید.
  • امکان ادغام با کتابخانه های گزارش خرابی را فراهم می کند.

فوراً اولین مزیت را خواهید دید. با ساختن و ارسال برنامه های بزرگتر، از بقیه قدردانی خواهید کرد.

مرحله 1: الوار را به Gradle اضافه کنید

  1. از این پیوند به پروژه Timber در GitHub دیدن کنید و خط کد زیر عنوان دانلود را که با کلمه implementation شروع می شود کپی کنید. خط کد چیزی شبیه به این خواهد بود، اگرچه شماره نسخه ممکن است متفاوت باشد.
implementation 'com.jakewharton.timber:timber:4.7.1'
  1. در Android Studio، در نمای Project: Android، Gradle Scripts را گسترش دهید و فایل build.gradle (Module: app) را باز کنید.
  2. در قسمت وابستگی ها، خط کدی را که کپی کرده اید، قرار دهید.
dependencies {
   ...
   implementation 'com.jakewharton.timber:timber:4.7.1'
}
  1. برای بازسازی Gradle، روی پیوند Sync Now در سمت راست بالای Android Studio کلیک کنید. ساخت باید بدون خطا اجرا شود.

مرحله 2: یک کلاس Application ایجاد کنید و Timber را مقداردهی اولیه کنید

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

Timber از کلاس Application استفاده می کند زیرا کل برنامه از این کتابخانه ورود به سیستم استفاده می کند، و کتابخانه باید یک بار، قبل از راه اندازی همه چیز، مقداردهی اولیه شود. در مواردی مانند این، می توانید کلاس Application را زیر کلاس قرار دهید و با پیاده سازی سفارشی خود، پیش فرض ها را لغو کنید.

پس از ایجاد کلاس Application خود، باید کلاس را در مانیفست اندروید مشخص کنید.

  1. در بسته dessertclicker ، یک کلاس Kotlin جدید به نام ClickerApplication کنید. برای انجام این کار، برنامه > java را گسترش دهید و روی com.example.android.dessertclicker کلیک راست کنید. New > Kotlin File/Class را انتخاب کنید.
  2. نام کلاس را ClickerApplication گذاشته و Kind را روی Class قرار دهید. روی OK کلیک کنید.

Android Studio یک کلاس ClickerApplication جدید ایجاد می کند و آن را در ویرایشگر کد باز می کند. کد به شکل زیر است:

package com.example.android.dessertclicker

class ClickerApplication {
}
  1. تعریف کلاس را به عنوان زیر کلاس Application تغییر دهید و در صورت لزوم کلاس Application را وارد کنید.
class ClickerApplication : Application() {
  1. برای لغو onCreate() ، Code > Override Methods را انتخاب کنید یا Control+o را فشار دهید.
class ClickerApplication : Application() {
   override fun onCreate() {
       super.onCreate()
   }
}
  1. در داخل onCreate() ، کتابخانه Timber را مقداردهی اولیه کنید:
override fun onCreate() {
    super.onCreate()

    Timber.plant(Timber.DebugTree())
}

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

  1. AndroidManifest.xml را باز کنید.
  2. در بالای عنصر <application> ، یک ویژگی جدید برای کلاس ClickerApplication اضافه کنید، تا Android بداند که از کلاس Application شما به جای کلاس پیش فرض استفاده کند.
<application
   android:name=".ClickerApplication"
...

مرحله 3: بیانیه‌های گزارش چوب را اضافه کنید

در این مرحله، Log.i() خود را برای استفاده از Timber تغییر می‌دهید، سپس لاگ را برای تمام متدهای چرخه حیات دیگر پیاده‌سازی می‌کنید.

  1. MainActivity را باز کنید و به onCreate() بروید. Log.i() را با Timber.i() جایگزین کنید و تگ log را حذف کنید.
Timber.i("onCreate called")

مانند کلاس Log ، Timber نیز از متد i() برای پیام های اطلاعاتی استفاده می کند. توجه داشته باشید که با Timber نیازی به اضافه کردن برچسب لاگ ندارید. Timber بطور خودکار از نام کلاس به عنوان تگ log استفاده می کند.

  1. به طور مشابه، تماس Log را در onStart() تغییر دهید:
override fun onStart() {
   super.onStart()

   Timber.i("onStart Called")
}
  1. برنامه DessertClicker را کامپایل و اجرا کنید و Logcat را باز کنید. توجه داشته باشید که شما همچنان همان پیام‌های log را برای onCreate() و onStart() می‌بینید، فقط اکنون Timber آن پیام‌ها را تولید می‌کند، نه کلاس Log .
  2. بقیه روش‌های چرخه حیات را در MainActivity خود نادیده بگیرید و برای هر یک از آنها عبارت‌های Timber log را اضافه کنید. این هم کد:
override fun onResume() {
   super.onResume()
   Timber.i("onResume Called")
}

override fun onPause() {
   super.onPause()
   Timber.i("onPause Called")
}

override fun onStop() {
   super.onStop()
   Timber.i("onStop Called")
}

override fun onDestroy() {
   super.onDestroy()
   Timber.i("onDestroy Called")
}

override fun onRestart() {
   super.onRestart()
   Timber.i("onRestart Called")
}
  1. دوباره DessertClicker را کامپایل و اجرا کنید و Logcat را بررسی کنید. این بار توجه داشته باشید که علاوه بر onCreate() و onStart() ، یک پیام گزارش برای بازگشت به تماس چرخه حیات onResume() نیز وجود دارد.

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

  • onCreate() برای ایجاد برنامه.
  • onStart() تا آن را شروع کرده و روی صفحه نمایش نمایان کند.
  • onResume() برای تمرکز فعالیت و آماده کردن آن برای تعامل کاربر با آن.

با وجود نام، onResume() هنگام راه اندازی فراخوانی می شود، حتی اگر چیزی برای از سرگیری وجود نداشته باشد.

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

مورد استفاده 1: باز و بسته کردن فعالیت

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

  1. برنامه DessertClicker را کامپایل و اجرا کنید، اگر قبلاً اجرا نشده است. همانطور که مشاهده کردید، فراخوانی های onCreate() ، onStart() و () onResume() زمانی که فعالیت برای اولین بار شروع می شود فراخوانی می شوند.
  2. چند بار روی کیک کوچک ضربه بزنید.
  3. روی دکمه Back در دستگاه ضربه بزنید. در Logcat توجه کنید که onPause() , onStop() و onDestroy() به این ترتیب فراخوانی می شوند.

    در این حالت، استفاده از دکمه Back باعث می شود که فعالیت (و برنامه) به طور کامل بسته شود. اجرای متد onDestroy() به این معنی است که فعالیت به طور کامل بسته شده است و می توان زباله ها را جمع آوری کرد. جمع آوری زباله به پاکسازی خودکار اشیایی که دیگر از آنها استفاده نخواهید کرد اشاره دارد. پس از فراخوانی onDestroy() ، سیستم عامل می‌داند که آن منابع قابل حذف هستند و شروع به پاکسازی حافظه می‌کند.

    همچنین اگر کد شما به صورت دستی متد finish() را فراخوانی کند، یا اگر کاربر به زور از برنامه خارج شود، ممکن است فعالیت شما به طور کامل خاموش شود. (به عنوان مثال، کاربر می تواند با کلیک بر روی X در گوشه پنجره، برنامه را در صفحه نمایش اخیر به اجبار ترک کند.) اگر برنامه شما برای مدت طولانی روی صفحه نبوده باشد، سیستم اندروید نیز ممکن است فعالیت شما را به خودی خود خاموش کند. زمان طولانی. Android این کار را برای حفظ باتری و اجازه استفاده از منابع برنامه شما توسط برنامه های دیگر انجام می دهد.
  4. برای بازگشت به برنامه از صفحه نمایش اخیر استفاده کنید. Logcat اینجاست:


    اکتیویتی در مرحله قبل از بین رفت، بنابراین وقتی به برنامه برگشتید، اندروید یک اکتیویتی جدید راه اندازی می کند و متدهای onCreate() , onStart() و onResume() را فراخوانی می کند. توجه داشته باشید که هیچ یک از آمار DessertClicker مربوط به فعالیت قبلی حفظ نشده است.

    نکته کلیدی در اینجا این است که onCreate() و onDestroy() فقط یک بار در طول عمر یک نمونه فعالیت فراخوانی می شوند: onCreate() برای مقداردهی اولیه برنامه برای اولین بار و onDestroy() برای پاکسازی منابع استفاده شده توسط برنامه شما

    onCreate() یک مرحله مهم است. این همان جایی است که تمام مقداردهی اولیه شما به آنجا می رود، جایی که طرح را برای اولین بار با افزایش دادن آن تنظیم می کنید، و جایی که متغیرهای خود را مقداردهی اولیه می کنید.

مورد استفاده 2: دور شدن از فعالیت و بازگشت به آن

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

هر بار که کاربر از آن فعالیت دور می شود، فعالیت شما به طور کامل بسته نمی شود:

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

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

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

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

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

  1. با اجرای برنامه DessertClicker، چند بار روی کیک کوچک کلیک کنید.
  2. دکمه Home را در دستگاه خود فشار دهید و Logcat را در Android Studio مشاهده کنید. بازگشت به صفحه اصلی، برنامه شما را در پس‌زمینه قرار می‌دهد تا اینکه برنامه را به طور کلی خاموش کنید. توجه داشته باشید که onPause() و متد onStop onStop() ) فراخوانی می شوند، اما onDestroy() نیست.


    با فراخوانی onPause() ، برنامه دیگر فوکوس ندارد. پس از onStop() ، برنامه دیگر روی صفحه نمایش قابل مشاهده نیست. اگرچه فعالیت متوقف شده است، شی Activity هنوز در حافظه در پس‌زمینه است. فعالیت از بین نرفته است. ممکن است کاربر به برنامه بازگردد، بنابراین Android منابع فعالیت شما را در اطراف نگه می دارد.
  3. برای بازگشت به برنامه از صفحه نمایش اخیر استفاده کنید. در Logcat توجه کنید که فعالیت با onRestart() onStart() مجدداً شروع می شود، سپس با onResume() از سر گرفته می شود.


    هنگامی که اکتیویتی به پیش زمینه باز می گردد، onCreate() دوباره فراخوانی نمی شود. شی اکتیویتی از بین نرفته است، بنابراین نیازی به ایجاد مجدد آن نیست. به جای onCreate() onRestart() فراخوانی می شود. توجه داشته باشید که این بار که فعالیت به پیش‌زمینه باز می‌گردد، عدد Desserts Sold حفظ می‌شود.
  4. حداقل یک برنامه غیر از DessertClicker را راه اندازی کنید تا دستگاه چند برنامه در صفحه اخیر خود داشته باشد.
  5. صفحه آخرین ها را باز کنید و یکی دیگر از فعالیت های اخیر را باز کنید. سپس به برنامه های اخیر برگردید و DessertClicker را به پیش زمینه بازگردانید.

    توجه داشته باشید که در Logcat همان تماس‌هایی را می‌بینید که وقتی دکمه Home را فشار دادید. onPause() و onStop() onStop زمانی که برنامه به پس‌زمینه می‌رود، و سپس onRestart() , onStart() و onResume() هنگامی که برمی‌گردد فراخوانی می‌شوند.

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

    پس onRestart() چطور؟ onRestart() بسیار شبیه onCreate() است. قبل از قابل مشاهده شدن اکتیویتی، هریک از () onCreate() onRestart() فراخوانی می شوند. onCreate() فقط بار اول فراخوانی می شود و onRestart() بعد از آن فراخوانی می شود. onRestart() مکانی برای قرار دادن کدی است که فقط در صورتی که فعالیت شما برای اولین بار شروع نشده باشد می خواهید آن را فراخوانی کنید.

مورد استفاده 3: تا حدی فعالیت را پنهان کنید

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

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

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

  1. با اجرای برنامه DessertClicker، روی دکمه اشتراک گذاری در سمت راست بالای صفحه کلیک کنید.




    فعالیت اشتراک‌گذاری در نیمه پایین صفحه ظاهر می‌شود، اما فعالیت همچنان در نیمه بالایی قابل مشاهده است.
  2. Logcat را بررسی کنید و توجه داشته باشید که فقط onPause() فراخوانی شده است.


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

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

    هر کدی که در onPause() اجرا می شود مانع از نمایش سایر چیزها می شود، بنابراین کد را در onPause() سبک وزن نگه دارید. به عنوان مثال، اگر یک تماس تلفنی وارد شود، کد موجود در onPause() ممکن است اعلان تماس ورودی را به تاخیر بیندازد.
  3. برای بازگشت به برنامه، خارج از گفتگوی اشتراک‌گذاری کلیک کنید و توجه کنید که onResume() فراخوانی شده است.

    هر دو onResume() onPause() با فوکوس ارتباط دارند. onResume() زمانی فراخوانی می شود که اکتیویتی فوکوس داشته باشد و onPause() زمانی فراخوانی می شود که فعالیت تمرکز خود را از دست بدهد.

چرخه عمر قطعه Android شبیه چرخه حیات فعالیت است، به علاوه چندین روش خاص قطعه.

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

هر صفحه در برنامه AndroidTrivia یک Fragment است.

برای ساده نگه داشتن کارها، به جای کتابخانه Timber، از API Logging Android در این کار استفاده می کنید.

  1. برنامه AndroidTrivia را از آخرین Codelab باز کنید یا کد راه حل AndroidTrivia را از GitHub دانلود کنید.
  2. فایل TitleFragment.kt را باز کنید. توجه داشته باشید که تا زمانی که برنامه را بازسازی نکنید، Android Studio ممکن است خطاهای الزام آور و خطاهای مرجع حل نشده را نشان دهد.
  3. به سمت پایین به onCreateView() بروید. توجه داشته باشید که اینجا جایی است که چیدمان قطعه پر شده و اتصال داده ها اتفاق می افتد.
  4. در بین خط setHasOptionsMenu() و آخرین فراخوانی برای بازگشت، یک دستور ورود به روش onCreateView() اضافه کنید:
setHasOptionsMenu(true)

Log.i("TitleFragment", "onCreateView called")

return binding.root
  1. درست در زیر onCreateView() ، برای هر یک از متدهای چرخه عمر قطعه باقیمانده، دستورهای گزارش را اضافه کنید. این هم کد:
override fun onAttach(context: Context?) {
   super.onAttach(context)
   Log.i("TitleFragment", "onAttach called")
}
override fun onCreate(savedInstanceState: Bundle?) {
   super.onCreate(savedInstanceState)
   Log.i("TitleFragment", "onCreate called")
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
   super.onActivityCreated(savedInstanceState)
   Log.i("TitleFragment", "onActivityCreated called")
}
override fun onStart() {
   super.onStart()
   Log.i("TitleFragment", "onStart called")
}
override fun onResume() {
   super.onResume()
   Log.i("TitleFragment", "onResume called")
}
override fun onPause() {
   super.onPause()
   Log.i("TitleFragment", "onPause called")
}
override fun onStop() {
   super.onStop()
   Log.i("TitleFragment", "onStop called")
}
override fun onDestroyView() {
   super.onDestroyView()
   Log.i("TitleFragment", "onDestroyView called")
}
override fun onDetach() {
   super.onDetach()
   Log.i("TitleFragment", "onDetach called")
}
  1. برنامه را کامپایل و اجرا کنید و Logcat را باز کنید.
  2. برای فیلتر کردن گزارش، I/TitleFragment را در قسمت جستجو تایپ کنید. هنگامی که برنامه شروع به کار کرد، Logcat چیزی شبیه تصویر زیر خواهد بود:

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

  • onAttach() : زمانی فراخوانی می شود که قطعه با فعالیت مالک آن مرتبط باشد.
  • onCreate() : مشابه onCreate() برای اکتیویتی، onCreate() برای قطعه فراخوانی می شود تا ایجاد قطعه اولیه (به غیر از layout) را انجام دهد.
  • onCreateView() : برای افزایش طرح بندی قطعه فراخوانی می شود.
  • onActivityCreated() : زمانی فراخوانی می شود که فعالیت مالک onCreate() کامل شود. تا زمانی که این متد فراخوانی نشود، قطعه شما نمی‌تواند به فعالیت دسترسی داشته باشد.
  • onStart() : زمانی فراخوانی می شود که قطعه قابل مشاهده شود. به موازات onStart() فعالیت.
  • onResume() : زمانی فراخوانی می شود که قطعه مورد نظر تمرکز کاربر را به دست آورد. به موازات onResume() فعالیت.
  1. برای ادامه به بازی چیزهای بی اهمیت روی دکمه Play ضربه بزنید و اکنون به Logcat توجه کنید.

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

  • onPause() : زمانی فراخوانی می شود که قطعه فوکوس کاربر را از دست بدهد. به موازات onPause() فعالیت.
  • onStop() : زمانی فراخوانی می شود که قطعه دیگر روی صفحه قابل مشاهده نباشد. به موازات onStop() فعالیت.
  • onDestroyView() : زمانی فراخوانی می شود که نمای قطعه دیگر مورد نیاز نباشد، برای پاکسازی منابع مرتبط با آن view.
  1. در برنامه، روی دکمه بالا (فلش در گوشه سمت چپ بالای صفحه) ضربه بزنید تا به قطعه عنوان بازگردید.


    این بار، onAttach() و onCreate() احتمالا برای شروع قطعه فراخوانی نشده اند. شی قطعه هنوز وجود دارد و همچنان به فعالیت مالک خود متصل است، بنابراین چرخه حیات دوباره با onCreateView() شروع می شود.
  2. دکمه Home دستگاه را فشار دهید. در Logcat توجه کنید که فقط onPause() و onStop() فراخوانی می شوند. این همان رفتاری است که برای فعالیت انجام می شود: بازگشت به خانه فعالیت و قطعه را در پس زمینه قرار می دهد.
  3. برای بازگشت به برنامه از صفحه نمایش اخیر استفاده کنید. همانطور که برای اکتیویتی اتفاق افتاد، متدهای onStart() و onResume() فراخوانی می شوند تا قطعه را به پیش زمینه بازگردانند.

پروژه اندروید استودیو: DessertClickerLogs

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

  • چرخه حیات فعالیت مجموعه ای از حالات است که از طریق آن یک فعالیت مهاجرت می کند. چرخه حیات فعالیت زمانی شروع می شود که فعالیت برای اولین بار ایجاد می شود و زمانی که فعالیت از بین می رود پایان می یابد.
  • وقتی کاربر بین فعالیت‌ها و داخل و خارج برنامه شما حرکت می‌کند، هر فعالیت بین حالت‌های چرخه حیات فعالیت حرکت می‌کند.
  • هر حالت در چرخه حیات فعالیت دارای یک روش برگشت تماس مربوطه است که می توانید در کلاس Activity خود لغو کنید. هفت روش چرخه زندگی وجود دارد:
    onCreate()
    onStart()
    onPause()
    onRestart()
    onResume()
    onStop()
    onDestroy()
  • برای افزودن رفتاری که هنگام انتقال فعالیت شما به حالت چرخه حیات رخ می دهد، روش برگشت به تماس وضعیت را لغو کنید.
  • برای افزودن روش‌های لغو اسکلت به کلاس‌های خود در Android Studio، Code > Override Methods را انتخاب کنید یا Control+o را فشار دهید.

ورود به سیستم با Log

  • API ورود به سیستم Android، و به طور خاص کلاس Log ، به شما امکان می دهد پیام های کوتاهی را بنویسید که در Logcat در Android Studio نمایش داده می شوند.
  • از Log.i() برای نوشتن یک پیام اطلاعاتی استفاده کنید. این متد دو آرگومان می گیرد: تگ log، معمولاً نام کلاس، و پیام log، یک رشته کوتاه.
  • از پانل Logcat در Android Studio برای مشاهده گزارش‌های سیستم، از جمله پیام‌هایی که می‌نویسید، استفاده کنید.

ورود به سیستم با چوب

Timber یک کتابخانه ورود به سیستم است که دارای چندین مزیت نسبت به API ورود به سیستم اندروید است. به طور خاص، کتابخانه Timber :

  • بر اساس نام کلاس تگ log را برای شما ایجاد می کند.
  • کمک می‌کند تا از نمایش گزارش‌ها در نسخه منتشرشده برنامه Android خود جلوگیری کنید.
  • امکان ادغام با کتابخانه های گزارش خرابی را فراهم می کند.

برای استفاده از Timber ، وابستگی آن را به فایل Gradle خود اضافه کنید و کلاس Application را برای مقداردهی اولیه آن گسترش دهید:

  • Application یک کلاس پایه است که شامل حالت برنامه جهانی برای کل برنامه شما است. یک کلاس Application پیش‌فرض وجود دارد که اگر آن را مشخص نکنید توسط Android استفاده می‌شود. می‌توانید زیرکلاس Application خود را برای راه‌اندازی کتابخانه‌های سراسر برنامه مانند Timber ایجاد کنید.
  • با افزودن ویژگی android:name به عنصر <application> در مانیفست اندروید، کلاس Application سفارشی خود را به برنامه خود اضافه کنید. این کار را فراموش نکنید!
  • از Timber.i() برای نوشتن پیام های گزارش با Timber استفاده کنید. این روش فقط یک آرگومان می گیرد: پیام برای نوشتن. تگ log (نام کلاس) به طور خودکار برای شما اضافه می شود.

دوره بی ادبی:

مستندات توسعه دهنده اندروید:

دیگر:

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

  • در صورت نیاز تکالیف را تعیین کنید.
  • نحوه ارسال تکالیف را با دانش آموزان در میان بگذارید.
  • تکالیف را نمره دهید.

مربیان می‌توانند از این پیشنهادات به اندازه‌ای که می‌خواهند استفاده کنند، و باید با خیال راحت هر تکلیف دیگری را که فکر می‌کنند مناسب است به آنها اختصاص دهند.

If you're working through this codelab on your own, feel free to use these homework assignments to test your knowledge.

Change an app

Open the DiceRoller app from Lesson 1. (You can download the DiceRoller app here if you don't have the app.) Add Timber support to that app, using the same process you did for the DessertClicker app. Override all the lifecycle callbacks, and add logging messages for each callback.

Answer these questions

Question 1

Which of the following is NOT an activity lifecycle state?

  • Started
  • Waiting
  • Created
  • Destroyed

Question 2

Which lifecycle method is called to make an activity visible?

  • onPause()
  • onVisible()
  • onStart()
  • onDestroy()

Question 3

Which lifecycle method is called to give an activity focus?

  • onResume()
  • onVisible()
  • onStart()
  • onFocus()

Question 4

When is onCreate() called in an activity?

  • Each time the activity is visible to the user.
  • Each time the activity returns from the background.
  • Only once, when the activity is created.
  • Only once, when the activity is resumed.

Submit your app for grading

Check to make sure the app has the following:

  • A dependency to Timber in the build.gradle file for the app.
  • A custom subclass of Application that initializes Timber in onCreate() .
  • An attribute for that custom subclass in the Android manifest.
  • Method overrides in MainActivity for all the lifecycle callback methods, with calls to Timber.i() for logging.

Start the next lesson: 4.2: Complex lifecycle situations

For links to other codelabs in this course, see the Android Kotlin Fundamentals codelabs landing page .