کانال بله, جهت پشتیبانی و اطلاع رسانی کانال بله, جهت پشتیبانی و اطلاع رسانی
عضویت

آموزش Xamarin-آموزش چرخه فعاليت(Activity Lifecycle)

چرخه فعاليت(Activity Lifecycle)

فعالیت ها(Activities) یک بلوک اصلی اساسی از برنامه های آندروید هستند و می توانند در تعدادی از موقعیت های مختلف وجود داشته باشند. "چرخه فعالیت" با "instantiation" شروع می شود و با "destruction"به پایان می رسد ، و شامل بسیاری از states ها در این میان است. هنگامی که یک فعالیت را تغییر وضعیت می دهیم، روش "رویداد lifecycle" مناسب فرخوانده می شود،اعلان تغيير وضعيت فعاليت پيش بيني شده و اجازه دادن به آن براي اجراي کد براي انطباق با آن تغيير مي دهد. این مقاله چرخه عمر فعالیت ها را بررسی می کند و مسئولیتی را که فعالیت در طول هر یک از این تغییرات حالات به دست می دهد به عنوان بخشی از یک برنامه کاربردی قابل اعتماد و قابل اطمینان توضیح می دهد.

بررسی اجمالی

فعالیتها یک مفهوم برنامه نویسی غیر معمول برای Android است. در توسعه نرم افزارهای مرسوم معمولا یک روش اصلی استاتیک وجود دارد که برای اجرای برنامه اجرا می شود. با آندروید ،با این حال، چیزها متفاوت هستند. برنامه های کاربردی آندروید را می توان از طریق هر فعالیت ثبت شده در یک برنامه راه اندازی شد. در عمل، اکثر برنامه های کاربردی تنها یک فعالیت خاص را دارند که به عنوان نقطه ورود نرم افزار مشخص می شود. با این حال، اگر یک برنامه سقوط کند یا توسط سیستم عامل متوقف شود، سیستم عامل می تواند سعی کند برنامه را در آخرین activity باز یا هر جای دیگر درون activity stack قبلی، مجددا راه اندازی کند. علاوه بر این، سیستم عامل هنگامی که فعال نیست فعالیت های خود را متوقف می کند و اگر حافظه کم باشد، آنها را بازیابی می کند. در صورتی که یک فعالیت دوباره شروع شود باید توجه دقیق کرد که برنامه اجازه می دهد که وضعیت را به درستی بازگرداند، ، به ویژه اگر این فعالیت به داده های فعالیت های قبلی بستگی دارد.
چرخه عمر فعالیت به عنوان مجموعه ای از روش هایی که OS در طول چرخه عمر یک فعالیت می خواند، اجرا می شود. این روش ها توسعه دهندگان را قادر می سازد تا قابلیت های "وضعیت(state)" و الزامات مدیریت منابع برنامه های کاربردی خود را را که برای برآورده شدن لازم است، پیاده سازی کنند.
برای توسعه دهنده نرم افزار بسیار مهم است که نیازهای هر فعالیت را تجزیه و تحلیل کند تا تعیین شود که چه روش هایی که در چرخه زندگی فعال قرار می گیرند، باید اجرا شود. عدم انجام این کار می تواند ناپایداری برنامه، سقوط، نفوذ به منابع و احتمالا بی ثباتی سیستم عامل را منجر شود.
این فصل جزئیات چرخه عمر فعالیت را بررسی می کند از جمله:

  • Activity States
  • Lifecycle Methods
  • حفظ یک State از یک برنامه

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

چرخه فعاليت(Activity Lifecycle)

چرخه عمر فعالیت Android شامل مجموعه ای از روش های موجود در کلاس Activity می شود، که به توسعه دهنده یک framework مدیریت منابع رائه می کند. این framework به توسعه دهندگان اجازه می دهد تا نیازهای مدیریت منحصر به فرد حالات(state) را در هر یک از برنامه ها رعایت کنند و مدیریت آنها را به درستی مدیریت کند.

حالات فعالیت (Activity State)

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


آموزش Xamarin Android

این حالتها را می توان به 4 گروه اصلی تقسیم کرد:

  • فعالیت یا در حال اجرا(Active or Running) : فعالیت هایی که فعال هستند یا در حال اجرا هستند، در صورتی که در پیش زمینه(foreground) هستند، همچنین به عنوان بالای activity stack شناخته می شوند.این را بالاترین اولویت در آندرویید در نظر می گیرند و و به همین ترتیب توسط سیستم عامل در حالت افراطی کشته خواهد شد ، مانند این که اگر این فعالیت سعی در استفاده از حافظه بیشتری نسبت به حافظه موجود در دستگاه داشته باشد، این امر باعث می شود که رابط کاربر غیر فعال شود.
  • Paused : هنگامی که دستگاه به خواب(sleep) می رود، یا یک فعالیت هنوز قابل مشاهده است، اما تا حدی توسط یک فعالیت جدید، غیر کامل یا شفاف پنهان است، فعالیت در نظر گرفته شده متوقف شده است. فعالیت های متوقف شده هنوز زنده هستند، یعنی آنها تمام اطلاعات حالات و عضو ها را حفظ می کنند و به window manager متصل می شوند.این به عنوان دومین اولویت activity در آندرویید در نظر گرفته شده است و به همین ترتیب تنها توسط سیستم عامل کشته خواهد شد در صورتی که اگر کشتن این فعالیت، الزامات منابع مورد نیاز برای حفظ فعالیت " Active/Running " پایدار و responsive باشد، برآورده خواهد شد.
  • Stopped / Backgrounded زمینه - فعالیت هایی که به طور کامل توسط فعالیت های دیگری خاموش می شوند " Stopped " یا " background " در نظر گرفته می شود. فعالیت های متوقف شده هنوز هم سعی دارند اطلاعات حالت ها و عضو خود را تا زمان ممکن حفظ کنند ، اما فعالیت های متوقف شده به عنوان پایین ترین اولویت این سه حالت در نظر گرفته می شوند،به همین ترتیب، سیستم عامل ابتدا فعالیت های این ایالت را برای برآوردن نیازهای منابع فعالیت های اولویت بالاتر از بین می برد.
  • Restarted : برای یک فعالیت این است که در هر نقطه ممکن است از paused به stopped در چرخه عمر برود تا از حافظه توسط آندرویید حذف شود.اگر کاربر به فعالیت بخواهد برگردد باید فعالیت restarted یا راه اندازی شود ، حالت قبلی ذخیره شده خود را بازیابی کند ، و سپس به کاربر نمایش داده شود.

ایجاد مجدد فعالیت در پاسخ به تغییرات پیکربندی(Activity Re-Creation in Response to Configuration Changes)

برای ایجاد پیچیده تر امور، آندروید یک نقشه دیگر را در مخلوطی به نام تغییرات پیکربندی می اندازد. تغییرات پیکربندی عبارتند از فعالیت سریع "چرخه تخریب / بازسازی(destruction/re-creation)" که زمانی رخ می دهد که پیکربندی یک فعالیت تغییر می کند، مانند زمانی که دستگاه چرخانده می شود (و فعالیت لازم است که در حالت افقی یا عمودی دوباره ساخته شود)،هنگامی که صفحه کلید نمایش داده می شود (و به فعالیت یک فرصت برای تغییر اندازه خود ارائه شده است)،یا هنگامی که دستگاه در dock بین دیگران قرار گرفته است.
تغییرات پیکربندی همچنان باعث تغییراتی مشابه « Activity State» میشود که در طول توقف و راه اندازی مجدد فعالیت رخ می دهد. با این حال، برای اطمینان از این که برنامه در هنگام تغییر تنظیمات حساس به نظر می رسد و به خوبی عمل می کند، مهم است که آنها با بیشترین سرعت ممکن پردازش شوند. به همین دلیل، آندروید دارای یک API خاص است که می تواند در طول تغییرات پیکربندی مورد استفاده قرار گیرد. ما این را بعدا در بخش "مدیریت حالات در چرخه عمر" پوشش خواهیم داد.

Activity Lifecycle Methods (متدهای چرخه فعالیت)

" Android SDK " ، به علاوه، Xamarin.Android framework یک مدل قدرتمند برای مدیریت حالت فعالیت ها در یک برنامه را فراهم می کند. هنگامی که یک حالت فعالیت در حال تغییر است، این فعالیت توسط سیستم عامل اطلاع داده می شود که روش های خاصی را در آن فعالیت فرخوانی می کند. نمودار زیر این روش ها را در رابطه با چرخه عمر فعالیت نشان می دهد:


آموزش Xamarin Android

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

OnCreate

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

  • Creating views
  • Initializing variables
  • Binding static data to lists

"OnCreate" پارامتر "Bundle" را می گیرد ،که یک فرهنگ لغت برای ذخیره و انتقال اطلاعات حالت ها است و اشیاء بین فعالیت ها اگر " Bundle " null نباشد،این نشان می دهد که فعالیت دوباره راه اندازی شده است و باید حالت خود را از نمونه قبلی بازگرداند. کد زیر نشان دهنده نحوه بازیابی مقادیر از Bundle است:

protected override void OnCreate(Bundle bundle)
{
   base.OnCreate(bundle);

   string intentString;
   bool intentBool;

   if (bundle != null)
   {
      intentString = bundle.GetString("myString");
      intentBool = bundle.GetBoolean("myBool");
   }

   // Set our view from the "main" layout resource
   SetContentView(Resource.Layout.Main);
}

هنگامی که OnCreate به پایان رسید، آندروید OnStart را فرخوانی میکند.

OnStart

OnStart همیشه توسط سیستم پس از پایان OnCreate فرخوانی می شود. فعالیت ها ممکن است این روش را لغو کنند، اگر آنها نیاز به انجام هر کار خاصی درست قبل از اینکه فعالیت قابل مشاهده باشد،مانند تجدید ارزش فعلی دیدگاه ها در فعالیت. Refresh کردن values های views ها درون activity.آندرویید بعد از این متد بلافاصله OnResume را فراخوانی می کند.

OnResume

سیستم هنگامی که فعالیت آماده برای شروع تعامل با کاربر است، OnResume را فراخوانی می کند. فعالیت ها باید این متد ها را برای انجام کارهایی مانند:

  • افزایش نرخ فریم (یک کار مشترک در ساخت بازی)
  • شروع انیمیشن ها
  • Listening برای به روز رسانی GPS
  • نمایش دادن هر هشدار یا گفتگو مربوطه
  • مدیریت متصل کردن رویداد های خارجی

به عنوان مثال، قطعه کد زیر نشان می دهد که چگونه دوربین را راه اندازی کنیم:

public void OnResume()
{
    base.OnResume(); // Always call the superclass first.

    if (_camera==null)
    {
        // Do camera initializations here
    }
}

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

OnPause

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

  • تغییرات ذخیره نشده را به اطلاعات مداوم تحمیل کنید
  • نابود کردن یا پاک کردن اشیاء مصرفی دیگر
  • کاهش نرخ فریم و توقف انیمیشن ها
  • غیرفعال کردن مدیریت رویداد های خارجی یا مدیریت اعلان ها (به عنوان مثال کسانی که به سرویس وابسته هستند). این باید برای جلوگیری از نشت حافظه فعالیت انجام شود.
  • به همین ترتیب، اگر فعالیت هر گونه گفتگو یا هشدار را نمایش دهد، باید با روش Dysmiss () پاک شود.

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

public void OnPause()
{
    base.OnPause(); // Always call the superclass first

    // Release the camera as other activities might need it
    if (_camera != null)
    {
        _camera.Release();
        _camera = null;
    }
}

دو روش چرخه عمر وجود دارد که پس از OnPause فرخوانده می شود:

  • OnResume فرخوانده می شود اگر فعالیت به پیش زمینه(foreground) بازگردانده شود.
  • OnStop فرخوانده می شود اگر فعالیت در پس زمینه(background) قرار گیرد.

OnStop

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

  • فعالیت جدید آغاز شده است و این فعالیت را پوشش می دهد.
  • یک فعالیت فعلی به پیش زمینه(foreground) رسیده است.
  • فعالیت نابود شده است.

OnStop ممکن است همیشه در موقعیت های کم حافظه فرخوانده نشود ، مانند زمانی که آندروید برای منابع کمبود داشته و می تواند به درستی زمینه فعالیت را نداشته باشد. به همین دلیل، بهتر است که در هنگام آماده سازی فعالیت برای تخریب، OnStop فرخوانده نشود. روشهای بعدی چرخه زندگی که ممکن است بعد از این فرخوانده شوند OnDestroy خواهد بود اگر فعالیت از بین برود.، یا «OnRestart» اگر فعالیت دوباره به ارتباط با کاربر باز گردد.

OnDestroy

OnDestroy روش نهایی است که در قسمت Activity قبل از اینکه آن را نابود و کاملا از حافظه حذف شود، فرخوانده می شود. در موقعیت های شدید آندروید ممکن است فرآیند برنامه ای که میزبانی این فعالیت را انجام می دهد را از بین ببرد، که به این ترتیب "OnDestroy" را به حال خود رها نمی کند. اکثر فعالیت ها این روش را اجرا نمی کنند زیرا اکثر clean up و shut down در روش OnPause و OnStop انجام شده است. روش OnDestroy به طور معمول برای تمیز کردن منابع طولانی مدت که ممکن است منابع را از بین ببرد، overridde می شود. یک نمونه از این ممکن است موضوعات پس زمینه(background) است که در OnCreate آغاز شده است.
پس از آنکه فعالیت نابود شد، هیچ روش چرخه زندگی وجود نخواهد داشت.

OnRestart

OnRestart پس از اینکه برنامه شما متوقف شده است فراخوانده می شود، قبل از شروع دوباره. مثال خوبی از این می تواند زمانی باشد که کاربر بر روی یک فعالیت در برنامه دکمه Home را فشار دهد. هنگامی که این اتفاق می افتد OnPause و سپس روش OnStop فراخوانی می شود و فعالیت به پس زمینه منتقل شده ، اما نابود شده است. اگر پس از آن کاربر برای بازگرداندن برنامه با استفاده از task manager یا یک برنامه مشابه اقدام کند، آندروید روش OnRestart فعالیت را فراخوانی می کند.
دستورالعمل کلی برای نوع منطقی(logic) در OnRestart وجود ندارد. این به این دلیل است که OnStart همیشه بدون در نظر گرفتن اینکه آیا فعالیت ایجاد شده یا در حال راه اندازی مجدد است، همیشه به آن اشاره می شود، بنابراین هر گونه منابع مورد نیاز توسط Activity باید در OnStart ، به جای OnRestart، مقداردهی اولیه شود.
متد بعدی که بعد از چرخه عمر OnRestart فرخوانی می شود OnStart است.

بازگشت با Home(Back vs. Home)

بسیاری از دستگاه های Android دارای دو دکمه مجزا هستند: یک دکمه " Back " و یک دکمه " Home ". یک مثال از این را می توان در تصویر زیر از Android 4.0.3 مشاهده کرد:


آموزش Xamarin Android

اختلاف ظریف بین دو دکمه وجود دارد، هرچند که ظاهرا همانند قرار دادن یک برنامه در پس زمینه است.هنگامی که یک کاربر روی دکمه Back کلیک می کند، آنها به آندروید می گویند که این فعالیت انجام شده است. آندروید فعالیت را از بین می برد. در مقابل، هنگامی که کاربر دکمه Home را کلیک می کند، فعالیت صرفا در پس زمینه قرار می گیرد - Android این فعالیت را نمی کشد.

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

هنگامی که یک فعالیت متوقف شده یا نابود می شود، سیستم فرصتی برای ذخیره "وضعیت فعالیت" برای فرخوانی مجدد فراهم می کند. این وضعیت ذخیره شده به عنوان مثال state (حالت یا وضعیت)نامیده می شود.آندروید سه گزینه برای ذخیره حالت نمونه در طول Activity lifecycle فراهم می کند:

  • ذخیره مقادیر اولیه در " Dictionary " شناخته شده به عنوان " Bundle" است که آندروید برای ذخیره در state استفاده می کند.
  • ایجاد یک کلاس سفارشی که مقادیر پیچیده مانند بیت مپ ها را نگه می دارد. آندروید از این کلاس سفارشی برای ذخیره در state استفاده خواهد کرد.
  • دور زدن تغییر پیکربندی چرخه عمر و در نظر گرفتن مسئولیت کامل برای حفظ state در فعالیت.

این مقاله دو گزینه اول را پوشش می دهد.

Bundle State

گزینه اصلی برای ذخیره در حالت نمونه، استفاده از یک شیء dictionary (key / value) شناخته شده به عنوان " Bundle " است. به یاد بیاورید که هنگامی که یک فعالیت ایجاد شده است که روش OnCreate یک Bundle را به عنوان یک پارامتر انتقال می دهد،این " Bundle " را می توان برای بازگرداندن حالت نمونه مورد استفاده قرار داد. توصیه نمی شود از " Bundle" برای داده های پیچیده تر استفاده کنید که سریع یا آسان به جفت key / value (مانند بیت مپ ها) serializeنخواهد شد؛ بلکه باید برای مقادیر ساده مانند stringsها مورد استفاده قرار گیرد.
یک فعالیت روش هایی را برای ذخیره و بازیابی حالت نمونه در Bundle فراهم می کند:

  • OnSaveInstanceState : که توسط آندروید زمانی که فعالیت نابود شده است فراخوانده می شود. فعالیت ها می توانند این روش را به اجرا در آورند، در صورتی که نیاز به نگه داشتن کلیه مقادیر حالت key/value باشد.
  • OnRestoreInstanceState : این پس از متد OnCreate که به پایان می رسد فرخوانده می شود و و فرصتی دیگر برای یک فعالیت برای بازگرداندن حالت خود پس از مقدار دهی اولیه فراهم می کند.

نمودار زیر نشان می دهد که چگونه این روش ها استفاده می شود:


آموزش Xamarin Android

OnSaveInstanceState

OnSaveInstanceStateبه عنوان فعالیت متوقف خواهد شد. این یک پارامتر bundle را دریافت می کند که فعالیت می تواند حالت آن را ذخیره کند. هنگامی که یک دستگاه تغییر پیکربندی را تجربه می کند، یک فعالیت می تواند از شی "Bundle" استفاده کند که در حفظ وضعیت فعالیت با "Overriding" OnSaveInstanceState منتقل می شود. به عنوان مثال، کد زیر را در نظر بگیرید:

int c;

protected override void OnCreate (Bundle bundle)
{
  base.OnCreate (bundle);

  this.SetContentView (Resource.Layout.SimpleStateView);

  var output = this.FindViewById< TextView > (Resource.Id.outputText);

  if (bundle != null) {
    c = bundle.GetInt ("counter", -1);
  } else {
    c = -1;
  }

  output.Text = c.ToString ();

  var incrementCounter = this.FindViewById< Button > (Resource.Id.incrementCounter);

  incrementCounter.Click += (s,e) = > {
    output.Text = (++c).ToString();
  };
}

کد بالا یک عدد صحیح با نام "c" را افزایش می دهد وقتی یک دکمه به نام "increment Counter" کلیک می شود، نتیجه را در "TextView" به نام "output" نمایش می دهد. هنگامی که یک تغییر پیکربندی رخ می دهد - به عنوان مثال، هنگامی که دستگاه چرخش می کند- کد بالا مقدار "c" را از دست می دهد، زیرا "bundle" "null" خواهد بود، همانطور که در شکل زیر نشان داده شده است:


آموزش Xamarin Android

به منظور حفظ ارزش(value) c در این مثال، فعالیت می تواند OnSaveInstanceState را نادیده بگیرد،value را ذخیره کند در "bundle"همانطور که در زیر نشان داده شده است:

protected override void OnSaveInstanceState (Bundle outState)
{
  outState.PutInt ("counter", c);
  base.OnSaveInstanceState (outState);
}

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

c = bundle.GetInt ("counter", -1);
توجه :

مهم است که همیشه پیاده سازی پایه OnSaveInstanceState را فراخوانی کنیدبه طوری که وضعیت سلسله مراتب view همچنین می تواند ذخیره شود.

View State

"OverSaveInstanceState" مکانیزم مناسب برای ذخیره داده های گذرا در یک فعالیت در طول تغییرات جهت گیری است مانند شمارنده در مثال فوق. با این حال، اجرای پیش فرض OnSaveInstanceState برای مراقبت از ذخیره داده های گذرا در UI برای هر view است،تا زمانی که به هر view یک شناسه اختصاص داده باشد. به عنوان مثال، می گویند یک برنامه که دارای یک عنصر EditText در XML تعریف شده است به شرح زیر است:

< EditText android:id="@+id/myText"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"/ >

از آنجا که کنترل EditText دارای شناسه اختصاص یافته است، هنگامی که کاربر برخی از داده ها وارد می کند و دستگاه را می چرخاند ،داده ها هنوز نمایش داده می شوند، همانطور که در زیر نشان داده شده است:


آموزش Xamarin Android

OnRestoreInstanceState

OnRestoreInstanceState پس از OnStart فرخوانده می شود. این فعالیت یک فرصت را برای بازگرداندن هر حالت ای که پیش از این در OnSaveInstanceState قبلی ذخیره شده بود به یک Bundle فراهم می کند. با این حال این همان Bundle است که به OnCreate ارائه شده است.
کد زیر نشان می دهد چگونه حالت را می توان در OnRestoreInstanceState بازسازی کرد:

protected override void OnRestoreInstanceState(Bundle savedState)
{
    base.OnRestoreSaveInstanceState(savedState);
    var myString = savedState.GetString("myString");
    var myBool = savedState.GetBoolean("myBool");
}

این روش برای ارائه برخی " flexibility" در اطراف وجود دارد ، هنگامی که state باید بازسازی شود. گاهی اوقات بهتر است منتظر بمانید تا قبل از بازگرداندن حالت نمونه، تمام مقدمات اولیه انجام شود. علاوه بر این، یک subclass از یک فعالیت فعلی فقط می تواند مقدار خاصی را از حالت نمونه بازگرداند. در بسیاری از موارد لازم نیست که OnRestoreInstanceState را نادیده بگیریم، زیرا اکثر فعالیتها میتوانند با استفاده از bundle موجود در OnCreate حالت را بازیابی کنند.

Bundle Limitations

اگر چه OnSaveInstanceState برای ذخیره داده های گذرا آسان است، اما محدودیت هایی دارد:

  • در همه موارد فراخوانی نمی شود. برای مثال، با فشار دادن Home یا Back برای خروج از یک فعالیت ،با فراخوانی OnSaveInstanceState نتیجه نخواهد گرفت.
  • bundle منتقل شده به InSaveInstanceState برای اشیاء بزرگ، مانند تصاویر طراحی نشده است. در مورد اشیاء بزرگ ذخیره در object از OnRetainNonConfigurationInstance ترجیح داده شده ، همانطور که در زیر بحث شده است.
  • اطلاعات ذخیره شده با استفاده از bundle در واقع serialized شده که می تواند منجر به تاخیر شود.

حالت Bundle برای داده های ساده مفید است که از حافظه زیاد استفاده نمی کند، در حالی که " non-configuration instance data " برای داده های پیچیده تر مفید است یا داده هایی که برای بازیابی پیچیده است مانند یک سرویس وب یا یک query پیچیده پایگاه داده. " Non-configuration instance data " در صورت نیاز ذخیره می شود. در بخش بعدی OnRetainNonConfigurationInstance را به عنوان راهی برای حفظ انواع داده های پیچیده تر از طریق تغییرات پیکربندی معرفی می کنیم.

Persisting Complex Data

علاوه بر داده های مداوم(persisting data) در bundle ، آندروید همچنین از ذخیره کردن داده ها با overriding از OnRetainNonConfigurationInstance و بازگرداندن نمونه ای از یک Java.Lang.Object که حاوی اطلاعاتی است که همچنان ادامه دارد، پشتیبانی می کند. دو حالت اصلی برای استفاده از OnRetainNonConfigurationInstance جهت ذخیره در حالت وجود دارد:

  • آبجکت برگردانده شده از OnRetainNonConfigurationInstance با انواع داده های بزرگتر و پیچیده تر انجام می شود، زیرا حافظه این شی را حفظ می کند.
  • روش OnRetainNonConfigurationInstance در صورت تقاضا فرخوانده می شود، و تنها زمانی که مورد نیاز است. این نسبت به استفاده از manual cache ارزان تر است.

استفاده از OnRetainNonConfigurationInstance مناسب برای سناریوهایی است که هزینه بازیابی داده ها چندین بار گران است.مانند خدمات تماس اینترنتی. به عنوان مثال، کد زیر را در نظر بگیریدکه در توییتر جستجو میکند:

public class NonConfigInstanceActivity : ListActivity
{
  protected override void OnCreate (Bundle bundle)
  {
    base.OnCreate (bundle);
    SearchTwitter ("xamarin");
  }

  public void SearchTwitter (string text)
  {
    string searchUrl = String.Format("http://search.twitter.com/search.json?" + "q={0}&rpp=10&include_entities=false&" + "result_type=mixed", text);

    var httpReq = (HttpWebRequest)HttpWebRequest.Create (new Uri (searchUrl));
    httpReq.BeginGetResponse (new AsyncCallback (ResponseCallback), httpReq);
  }

  void ResponseCallback (IAsyncResult ar)
  {
    var httpReq = (HttpWebRequest)ar.AsyncState;

    using (var httpRes = (HttpWebResponse)httpReq.EndGetResponse (ar)) {
      ParseResults (httpRes);
    }
  }

  void ParseResults (HttpWebResponse httpRes)
  {
    var s = httpRes.GetResponseStream ();
    var j = (JsonObject)JsonObject.Load (s);

    var results = (from result in (JsonArray)j ["results"] let jResult = result as JsonObject select jResult ["text"].ToString ()).ToArray ();

    RunOnUiThread (() => {
      PopulateTweetList (results);
    });
  }

  void PopulateTweetList (string[] results)
  {
    ListAdapter = new ArrayAdapter (this, Resource.Layout.ItemView, results);
  }
}

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


آموزش Xamarin Android

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

public class NonConfigInstanceActivity : ListActivity
{
  TweetListWrapper _savedInstance;

  protected override void OnCreate (Bundle bundle)
  {
    base.OnCreate (bundle);

    var tweetsWrapper = LastNonConfigurationInstance as TweetListWrapper;

    if (tweetsWrapper != null) {
      PopulateTweetList (tweetsWrapper.Tweets);
    } else {
      SearchTwitter ("xamarin");
    }

    public override Java.Lang.Object OnRetainNonConfigurationInstance ()
    {
      base.OnRetainNonConfigurationInstance ();
      return _savedInstance;
    }

    ...

    void PopulateTweetList (string[] results)
    {
      ListAdapter = new ArrayAdapter< string > (this, Resource.Layout.ItemView, results);
      _savedInstance = new TweetListWrapper{Tweets=results};
    }
}

حالا وقتی دستگاه چرخانده می شود، نتایج اصلی از ویژگی LastNonConfiguartionInstance بازیابی می شوند. در این مثال، نتایج شامل یک رشته [] حاوی توییت است. از آنجا که OnRetainNonConfigurationInstance نیاز به یک Java.Lang.Object دارد،رشته [] در یک کلاس قرار دارد که subclasses >> Java.Lang.Object است همانطور که در زیر نشان داده شده است:

class TweetListWrapper : Java.Lang.Object
{
  public string[] Tweets { get; set; }
}

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

TextView _textView;

protected override void OnCreate (Bundle bundle)
{
  base.OnCreate (bundle);

  var tv = LastNonConfigurationInstance as TextViewWrapper;

  if(tv != null) {
    _textView = tv;
    var parent = _textView.Parent as FrameLayout;
    parent.RemoveView(_textView);
  } else {
    _textView = new TextView (this);
    _textView.Text = "This will leak.";
  }

  SetContentView (_textView);
}

public override Java.Lang.Object OnRetainNonConfigurationInstance ()
{
  base.OnRetainNonConfigurationInstance ();
  return _textView;
}

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

خلاصه

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

1397/03/12 2884 1065
رمز عبور : tahlildadeh.com یا www.tahlildadeh.com
نظرات شما

نظرات خود را ثبت کنید...