کاتلین کوروتین چیست و دارای چه ویژگی هایی می‌باشد ؟

با آموزش کاتلین کوروتین در خدمت شما عزیزان کدایت هستیم . شاید شما هم در طول برنامه نویسی خودتون کلمه های مانند Thread ، Async Task و Rxjava  و همچنین Kotlin coroutine به گوشتان خورده باشد . ما امروز یاد خواهیم گرفت که کاتلین کوروتین چیست ؟ و چه کارایی برای ما دارد ؟ و تفاوت آن با مفاهیم مطرح شده بالا در چیست.

کاتلین کوروتین چیست ؟

اگربخواهم خیلی ساده  برای شما بگویم ، کوروتین دقیقا مانند Thread عمل می کند ولی ترد نیست . از کروتین برای برنامه نویسی به صورت غیر همزمان یا همان asynchronous استفاده میشود .نگران نباشید در ادامه توضیح خواهم داد که کدنویسی همزمان و غیره همزمان چیست و چه مزایایی دارد . در ترد اصلی یا همان Main Thread ، رابط کاربری یا UI و هر چیزی که به UI ما مربوط است قرار دارد .

اگر ما بخواهیم درخواست دیگری که نسبتا هم سنگین است را در این Thread انجام دهیم .این کار Thread ما را به خود مشغول می کند و به اصطلاح main Thread ما دیگر نمی‌تواند رابط کاربری را برای ما نمایش دهد و برنامه ما به اصطلاح crash  و مسدود می‌شود .

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

به چه منظوری از Kotlin Coroutine استفاده می‌شود

فرض کنید من یک  تابع دارم که برای شبکه در Main Thread  درخواست ارسال می کند . البته بزارید یه نکته هم داخل پارانتز براتون بگم (به Thread اصلی Main Thread یا UI Thread می گویند و به ترد های دیگر که در پس زمینه به صورت موازی اجرا می شوند Helper Thread میگویند .) با این کار ترد اصلی به کل مشغول میشود. و تا زمانی که درخواست شبکه ما انجام نشود کل thread اصلی مشغول هست و UI ما به درستی نمایش داده نمیشود. و این که ترد اصلی ما مشغول باشد فکر خوبی نیست .

کار درستی که ما باید انجام دهیم این است که تمامی کار ها و فعالیت های نامرتبط با UI برنامه خودمان را در یک Thread مجزای دیگر انجام دهیم . در این زمان است که کاتلین کوروتین  (kotlin coroutines ) وارد عمل می‌شود . در واقع ما با کمک کوروتین برنامه نویسی غیر همزمان یا Asynchronous را انجام می‌دهیم  تغییراتی که ما باید انجام شود تا از کاتلین کوروتین استفاده کنیم این هست که در پشت تابع کلمه Suspend را به کار ببریم .

کدنویسی غیر همزمان یا Asynchronous در کاتلین کوروتین

Asynchronous در کاتلین کوروتین

کار Suspend  این است که به کامپایلر کاتلین بگوید که تابع ما در یک کوروتین (Coroutines) اجرا می‌شود و اینکه ما یک تابع کوروتین را فقط می‌توانیم از یک روال مشترک یا یک تابع Suspend دیگر فراخوانی کنیم.

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

کد نویسی Asynchronous یا synchronous چیست ؟

کدنویسی synchronous یا همزمان یعنی  زمانی که من چندین task دارم، ابتدا تسک اول انجام می‌شود و بعد از اینکه تمام شد  task دومی شروع می‌گردد و به ترتیب تا آخر  ادامه می‌یابد .  ولی کدنویسی Asynchronous یا غیر همزمان این‌گونه نیست و هر چند تا task که داشته باشیم به صورت موازی اجرا می‌شوند. و شروع Task ای نیاز به تمام شدن تسک دیگری نیست .

تفاوت کوروتین با Rxjava , Thread , AsyncTask در چیست ؟

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

ٍRxJava : ما به عنوان برنامه نویس باید زمان خیلی زیادی بگذاریم تا به یک تجربه ای برسیم که بدون مشکلات و به صورت امن از این تکنولوژِی استفاده کنیم . بنابراین یک گزینه مناسبی نیست .

َAsyncTask :  این تکنولوژی نیز برای زمانی می‌باشد که کار های ما دارای حجم زیاد نباشد و کلا مناسب کارهای با حجم کم است .

Thread : بزرگترین مشکل ترد ها حافظه و کمبود آن است .

ولی در مقابل kotlin coroutines بسیار سبک است و کار ما را خیلی خیلی آسان تر کرده است.

چه مشکلاتی با آمدن کاتلین کوروتین برطرف شده است؟

  1. با وجود کاتلین کوروتین دیگر در UI Theard یا Main Thread کار های طولانی مدت انجام نمی‌شود و کوروتین آن‌ها را مسدود می‌کند.
  2. و مشکل دیگر که حل شده است این می‌باشد که ما میتوانیم تابع Suspend را در Thread اصلی صدا بزنیم
  3. در واقع کوروتین کد های مارا ساده می‌کند تا ما بتوانیم کارهای طولانی مدت را به راحتی مدیریت کنیم .
مطالب پربازدید:زبان کاتلین چه ویژگی هایی دارد ؟

Coroutine دارای ویژگی های است

Lightweight : به دلیل پشتیبانی از Suspend ها می‌توانیم بسیاری از Coroutine ها را در یک رشته اجرا کنید. که این امر باعث مسدود شدن رشته ای که کوروتین روی آن درحال اجرا است نمی‌گردد.

Fewer Memory Leaks : از همزمانی ساخت یافته برای اجرای عملیات در یک Scope استفاده می‌شود.

یک پارچه سازی Jetpack : بسیاری از کتابخانه های Jetpack دارای برنامه های افزودنی است که پشتیبانی کامل از کوروتین را ارائه می‌کنند.برخی از کتابخانه ها هم محدوده کاری خود را ارائه می‌دهند که می‌توانیم از آن برای همزمانی ساختار یافته استفاده کنید.

کوروتین اسکوپ هایی که در کاتلین مورد استفاده قرار می‌گیرد

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

Global scope در kotlin coroutine

Global scope در kotlin coroutine

LifeCycle scope :یک اسکوپی است که به Lifecycle هر Object یا فعالیتی مانند Activity و یا Fragment وابسته می‌باشد. و زمانی که این فعالیت از بین می‌رود ، این Scope نیز به صورت خودکار لغو می‌شود.این کار برای زمانی است که ما می‌خواهیم کلیه کار هایی که در پس زمینه اجرا می‌شود وکاربر نیز برای مدتی از آن دور شده را لغو کنیم .

LifeCycle scope در کاتلین کوروتین

LifeCycle scope در کاتلین کوروتین

Viewmodel scope :این اسکوپی میباشد که به Lifecycle ویو مدل گره خورده است . زمانی که Viewmodel از بین می‌رود آن برنامه هایی که در این Scope راه اندازی شده است به طور خودکار لغو می‌باشد . وقتی که کاربر از رابط کاربری دور بماند ودیگر قابل مشاهده نباشد . این کار برای لغو کار های background جاری مفید است .

Viewmodel scope در kotlin coroutine

Viewmodel scope در kotlin coroutine

Coroutine builders چیست ؟

همانطور که از اسمش معلوم است کوروتین بیلدیر ها یک روش مناسب برای ساخت کوروتین است . و به دلیل اینکه خودشان را Suspend نمی‌کنند میتوان آنها را از کد های غیره Suspend یا هر قطعه کد دیگر فراخوانی کرد .درواقع Coroutine Builder ها مانند یک لینک بین بخش های Suspend وغیره Suspend  کد ما عمل می‌کنند.  و اما کاتلین کوروتین بیلدیر های معروف به شرح زیر است .

Coroutine builders در کاتلین کوروتین

runblocking : همان طور که از اسم آن مشخص می‌باشد یک Coroutine Builder ای است که رشته فعلی را مسدود می‌کند.تا زمانی که تمامی وظایف کاری  تمام شود . اینجا سوالی پیش می آید و آن هم این است که زمانی که ما به طور واضح نمی‌خواهیم Thread خودمان را مسدود کنیم چرا از runBlocking باید استفاده کنیم؟

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

Launch : یک کوروتین جدید را راه اندازی می‌کند بدون اینکه نتیجه ای را برای Caller برگرداند . و همچنین اجازه میدهد تا یک کوروتین در پس زمینه شروع کنیم

async : واما یکی از بهترین Coroutine Builder ها Async می‌باشد . یک کوروتین بیلدیرایی می‌باشد که یک مقدار را به Caller برمی‌گرداند . و ما می‌توانیم از Async استفاده کنیم و یک کوروتین ایجاد کنیم و کار های سنگین خودمون را روی آن انجام دهیم . و نکته دیگر این است که زمانی که شما نیازی ندارید به اینکه چیزی برای Caller برگردانید پس نیاز نیست که از آن استفاده کنیم .

نکته : delay در کاتلین یک تابع Suspend است  که بدون این که thread اصلی ما را مسدود کند یک کوروتین را به تاخیر می اندازد . و بعد از یک مدت زمان مشخص(مثال:3000L)کار روتین را از سر می‌گیرد.

به چه دلیل نباید از Global Scope استفاده کرد؟

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

نکته 1 :   اسناد رسمی می‌گوید که کوروتین ها thread ها Light weight هستند . این وزن سبک به این معنی است که ایجاد کوروتین ها موضوعات جدید را اختصاص نمی‌دهد.

نکته 2 : کوروتین ها Thread های سبک وزنی هستند که mainThread را مسدود نمی‌کنند. ولی در عین حال امکان فراخوانی تابع Suspend را در main Threadرا فراهم می‌کند.

نکته 3: تابع Suspend ، تابعی است که قابلیت تعلیق اجرای کوروتین فعلی را بدون مسدود کردن Thread ای که در جریان  هست را دارد . همچنین این تابع میتواند در نقطه ای ، اجرا را از سر بگیرد. همچنین ویژگی تعلیق تابع Suspend به ما کمک می‌کند تا کدهای نا‌همزمان  را به صورت همزمان بنویسیم.

نکته 4 : نکته مهم دیگر این است که تابع های Suspend خود غیرهمزمان یا Asynchrouns نیستند.

Dispatchers یا توزیع کننده  درkotlin coroutines  چیست ؟

Dispatcher  یا توزیع کننده یک قابلیت ضروری است برای تصمیم گیری در مورد اجرای کوروتین ها در روی Thread های مختلف:

انواع Dispatcher  :

بسته به کاری که کوروتین  قرار است انجام دهد. چهار نوع Dispatchers وجود دارد:

  1.  توزیع کننده Default
  2. توزیع کننده Main
  3. توزیع کننده IO
  4. توزیع کننده  Unconfined
تشریح انواع توزیع کننده (Dispatcher) در کوروتین

انواع توزیع کننده (Dispatcher) در کوروتین

  1. دیسپچر پیش فرض برای زمانی می‌باشد که یکسری توابع سنگین در CPU انجام می‌دهیم . اگر فراموش کنیم که ِDispatvher خودتون  را انتخاب کنیم، این توزیع کننده به طور پیش فرض انتخاب می شود. و اما syntax آن نیز به شکل زیر میباشد .

    launch(Dispatchers.Default)

  2. این توزیع کننده زیاد استفاده نمی شود. فقط زمانی که بخواهیم با رابط کاربری در برنامه های اندروید خود تعامل داشته باشم استفاده می شود.  اگر می‌خواهیم از این استفاده کنیم، ابتدا باید دیسپچری را با استفاده از آن تنظیم کنیم Dispatchers.setMain(dispatcher) .launch(Dispatchers.Main)
  3. این Dispatcher نیز برای عملیات شبکه و دیسک است .launch(Dispatchers.IO)
  4. یک توزیع کننده Unconfined در کاتلین کوروتین به یک موضوع خاص محدود نمی شود.  launch(Dispatchers.Unconfined)

در قسمت پایین من یک مثالی از Dispatcher ها برای شما اماده کردم .

نمونه ای از Dispatcher ها در کوروتین

مثالی از Dispatcher ها در کوروتین

برای استفاده از کوروتین ها به چه چیز هایی نیازمندیم ؟

  • در ابتدا ما باید کتابخانه های کاتلین کوروتین را به برنامه خودمون اضافه کنیم .
  • Scope ، دامنه یا جایی که کوروتین در انجا می‌خواهد اجرا شود .اسکوپ مرز های اجرای یک برنامه کاری را مشخص می‌کندبا ازبین رفتن یک فعالیت باید تمامی کوروتین های مربوط به آن نیز به صورت خودکار از بین رود.
  •  ِDispatcher ها  برای تصمیم‌گیری در مورد اولویت اجرای Threadها می‌باشد .
  • Coroutine Builder : وظیفه ساخت و در مواقعی هم راه اندازی کوروتین را بر عهده دارد .
  • Job :نشان می‌دهد که کار ناهمزمان می‌باشد .
 اسکوپ فانکشن های معروف کتابخانه کاتلین کوروتین:
  • delay:این تابع کوروتین فعلی را برای مدت مشخصی به حالت تعلیق در می آورد و یک برنامه کاربری را برای مدت مشخصی متوقف می‌کند.
  • yield : این تابع کنترل را به سایر برنامه های که در حال  اجرا می‌باشد می‌دهد .با این کار ما به کوروتین های دیگر اجازه می‌دهیم تا در جای خود در حالت بیکار اجرا شوند. و به نوعی عملکرد کوروتین ها را بهبود ببخشیم .

خلاصه مطالب

ما در این پست در مورد کوروتین ها حرف زدیم و فهمیدیم که کاتلین کوروتین چیست ؟ چه تفاوت های با Thread ،AsyncTask و Rxjava دارد .به کمک kotlin coroutine  کار های سنگین و پیجیده در main thread انجام نمی‌شود و همین امر نیز باعث این  می‌شود که Thread اصلی ما مسدود نشود . فهمیدیم که Coroutine builders  ها یک روش مناسب و مفید برای ساخت و راه اندازی کوروتین ها می‌باشد. نکته دیگر این که با کدنویسی همزمان و غیره همزمان نیز آشنا شدیم

موفق باشید

 

برای امتیاز به این نوشته کلیک کنید!
[کل: 9 میانگین: 5]
اشتراک‌گذاری

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

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *