launch — Coroutine Builder در Kotlin است که کروتین را بدون بازگرداندن نتیجه راهاندازی میکند و شیء Job را برای مدیریت اجرا بازمیگرداند. این builder الگوی fire-and-forget را پیادهسازی میکند: کروتین کار خود را در نخ پسزمینه آغاز میکند و به طور خودکار پایان مییابد. به گفته مستندات JetBrains، 2024، launch روش اصلی راهاندازی وظایف موازی در Kotlin Coroutines است.
نکات کلیدی
launch — یک تابع توسعهدهنده Kotlin است که از طریق import kotlinx.coroutines در دسترس بوده و یک کروتین جدید در CoroutineScope مشخص شده ایجاد میکند. برخلاف توابع معمولی، کد داخل launch به صورت همروند اجرا میشود — کروتین میتواند بدون مسدود کردن نخ معلق (suspend) شده و بعداً از سر گرفته شود.
Builder launch بلوک ساختمانی اساسی مدل کروتین Kotlin است. این builder مقدار محاسبهشده را بازنمیگرداند، اما شیء Job را بازمیگرداند که امکان کنترل اجرای کروتین را فراهم میکند. تمام کروتینهای فرزندی که از طریق launch در داخل کروتین دیگری راهاندازی میشوند، به والد متصل میشوند.
Builder launch به عنوان یک تابع inline با چند پارامتر تعریف میشود: CoroutineScope، CoroutineContext، CoroutineStart و suspend-block. پارامترها مقادیر پیشفرض دارند که launch را برای سناریوهای معمولی راحت میسازد.
public fun CoroutineScope.launch(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> Unit
): Job
پارامتر context CoroutineContext را میپذیرد که توزیعکننده، مدیریتکننده استثنا و عنصر نامگذاری شده را ترکیب میکند. بیشتر اوقات Dispatchers.IO، Dispatchers.Main یا SupervisorJob برای جداسازی خطاها ارسال میشود.
Job — شیء برگشتی است که چرخه حیات کروتین را نشان میدهد. Job میتواند در حالتهای زیر باشد: New، Active، Completing، Completed، Cancelling، Cancelled. هر حالت وضعیت اجرا را منعکس کرده و امکان واکنش به تغییرات را فراهم میکند.
val job = CoroutineScope(Dispatchers.IO).launch {
repeat(10) { i ->
delay(1000L)
println("پیشرفت: $i")
}
}
println("Job فعال است: ${job.isActive}")
delay(2500L)
job.cancel()
println("Job لغو شده است: ${job.isCancelled}")
Job از سلسلهمراتب پشتیبانی میکند: اگر کروتین والد لغو شود، تمام کروتینهای فرزند به طور خودکار لغو میشوند. SupervisorJob این رفتار را تغییر میدهد — کروتینهای فرزند با خطای یکی از آنها لغو نمیشوند.
همروندی ساختاریافته به این معناست که هر کروتین در یک CoroutineScope مشخص راهاندازی میشود و scope تا زمانی که تمام کروتینهای فرزند کار خود را تمام نکنند، پایان نمیپذیرد. launch به طور کامل از این اصل پشتیبانی میکند — کروتینهایی که در داخل کروتین دیگری راهاندازی میشوند، فرزندان آن هستند.
در راهاندازی تودرتوی launch، یک درخت از کروتینها تشکیل میشود. کروتین والد منتظر تکمیل تمام فرزندان میماند که ترتیب اجرای قابل پیشبینی را تضمین کرده و مدیریت منابع را ساده میکند.
fun main() = runBlocking {
launch {
launch {
delay(1000L)
println("فرزند 1 تکمیل شد")
}
launch {
delay(500L)
println("فرزند 2 تکمیل شد")
}
println("همه فرزندان قبل از این خط تکمیل شدند")
}
}
این رفتار با همروندی مبتنی بر نخ متفاوت است، جایی که نخهای فرزند به والد متصل نیستند. در کروتینها، والد پایان نمییابد تا زمانی که همه فرزندان کار خود را تمام کنند.
مدیریت استثناها در launch به نوع Job بستگی دارد. برای Job معمولی، استثناها به کروتین والد منتشر شده و آن را لغو میکنند. برای SupervisorJob یا SupervisorScope، استثناها جداسازی میشوند — خطای یک کروتین فرزند بر سایرین تأثیر نمیگذارد.
val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
scope.launch {
try {
riskyOperation()
} catch (e: Exception) {
println("گرفته شد: ${e.message}")
}
}
scope.launch {
println("این هنوز به لطف SupervisorJob اجرا میشود")
}
برای مدیریت سراسری استثناهای مدیریتنشده از CoroutineExceptionHandler استفاده میشود. این handler استثناهایی را که در داخل کروتین مدیریت نشدهاند، گرفته و امکان ثبت خطا بدون کرش برنامه را فراهم میکند.
در Android، launch به طور گسترده از ViewModel تا WorkManager استفاده میشود. الگوی اصلی استفاده از lifecycleScope در Fragment و viewModelScope در ViewModel برای لغو خودکار کروتینها هنگام پایان چرخه حیات کامپوننت است.
class ProfileViewModel : ViewModel() {
private val repository = UserRepository()
fun loadProfile(userId: String) {
viewModelScope.launch(Dispatchers.IO) {
val profile = repository.fetchProfile(userId)
withContext(Dispatchers.Main) {
_profileState.update { it.copy(profile = profile) }
}
}
}
}
viewModelScope به طور خودکار کروتینها را هنگام نابودی ViewModel لغو میکند. این کار نشت حافظه را حذف کرده و تضمین میکند که عملیاتهای پسزمینه پس از از دست رفتن زمینه ادامه نمییابند. علاوه بر این، میتوان از withContext برای جابجایی بین توزیعکنندهها استفاده کرد.
سوالات متداول
launch Job بازمیگرداند و نتیجه اجرا را بازنمیگرداند، در حالی که async برای دریافت نتیجه، Deferred<T> بازمیگرداند. launch برای عملیاتهای fire-and-forget استفاده میشود، async زمانی که باید منتظر بمانید و از مقدار بازگشتی استفاده کنید.
روی شیء Job ذخیره شده job.cancel() را فراخوانی کنید. برای لغو گروهی، کل CoroutineScope را از طریق scope.cancel() لغو کنید. کروتین باید همکاریکننده باشد — isActive را بررسی کند یا از توابع suspend قابل بررسی استفاده کند.
در داخل بلوک launch از try-catch استفاده کنید یا CoroutineExceptionHandler را در CoroutineContext قرار دهید. برای جداسازی خطاها از SupervisorJob استفاده کنید — در این صورت استثنا در یک کروتین فرزند، بقیه را لغو نمیکند.
خیر، launch یک تابع توسعهدهنده CoroutineScope است. بدون scope، کروتین نمیتواند از اصل همروندی ساختاریافته پیروی کند. از GlobalScope.launch با احتیاط استفاده کنید — این کار یک کروتین بدون اتصال به چرخه حیات ایجاد میکند.
تعداد محدود به پool نخهای توزیعکننده است. Dispatchers.Default از تعداد نخهایی برابر با تعداد هستههای CPU استفاده میکند. Dispatchers.IO تا ۶۴ نخ را پشتیبانی میکند. هنگام راهاندازی تعداد بیشتری کروتین، آنها در صف قرار میگیرند.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید