كيفية استدعاء دالة مع تأخير في Kotlin: دليل كامل مع كود

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

لماذا تحتاج هذا الآن

\n

تخيل: أنت تكتب تطبيقًا، وتحتاج إلى عرض إشعار للمستخدم بعد 5 ثوانٍ من الضغط على زر. أو تنفيذ طلب إلى الخادم بعد ثانيتين فقط من انتهاء المستخدم من كتابة النص. أو ببساطة إنشاء رسم متحرك جميل مع تأخير. بدون معرفة كيفية استدعاء دالة مع تأخير في Kotlin — لا يمكنك المضي قدمًا.

\n

هذا السؤال هو واحد من أكثر الأسئلة شيوعًا على Stack Overflow (آلاف المشاهدات!)، وليس بدون سبب. في Kotlin هناك 4 طرق كاملة لعمل استدعاء مؤجل، وكل منها مناسب لموقف معين. في هذه المقالة، سنشرحها جميعًا: من delay() البسيط في coroutines إلى Handler الكلاسيكي لنظام Android. ستعرف أي طريقة تختار ولماذا، والأهم من ذلك — سترى كودًا عمليًا يمكنك نسخه فورًا إلى مشروعك.

\n\n

الطريقة 1: Coroutines و delay() (حديثة ومفضلة)

\n

هذه هي الطريقة الأكثر أناقة وموصى بها في Kotlin الحديث. Coroutines هي خيوط خفيفة لا تمنع الخيط الرئيسي. طريقة delay() توقف coroutine مؤقتًا للوقت المحدد، ثم تستأنفها.

\n

للعمل مع coroutines، تحتاج إلى إضافة التبعية في build.gradle.kts:

\n
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0")
\n

وإليك كيف يبدو ذلك في الكود:

\n
import kotlinx.coroutines.*\n\nfun main() = runBlocking {\n    println("البداية: ${System.currentTimeMillis()}")\n\n    // تشغيل coroutine مع تأخير\n    launch {\n        delay(3000L) // انتظر 3 ثوانٍ\n        println("مرت 3 ثوانٍ: ${System.currentTimeMillis()}")\n        myDelayedFunction() // استدعاء الدالة المطلوبة\n    }\n\n    println("ننتظر... (سيتم تنفيذ هذا فورًا)")\n}\n\nfun myDelayedFunction() {\n    println("تم تنفيذ الدالة!")}\n
\n

هام: delay() هي دالة إيقاف مؤقت (suspend function). يمكن استدعاؤها فقط داخل coroutine أو دالة suspend أخرى. إذا حاولت استدعاء delay() خارج coroutine، فسيصدر المترجم خطأ.

\n\n

كيفية عمل استدعاء مؤجل في Android باستخدام coroutines

\n

في تطوير Android، تعتبر coroutines المعيار الفعلي. إليك مثال لـ Activity:

\n
import androidx.appcompat.app.AppCompatActivity\nimport android.os.Bundle\nimport kotlinx.coroutines.*\n\nclass MainActivity : AppCompatActivity() {\n\n    private val scope = CoroutineScope(Dispatchers.Main + SupervisorJob())\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        setContentView(R.layout.activity_main)\n\n        // بعد ثانيتين، عرض رسالة Toast\n        scope.launch {\n            delay(2000L)\n            showToast("مرت ثانيتان!")\n        }\n    }\n\n    private fun showToast(message: String) {\n        android.widget.Toast.makeText(this, message, android.widget.Toast.LENGTH_SHORT).show()\n    }\n\n    override fun onDestroy() {\n        super.onDestroy()\n        scope.cancel() // إلغاء جميع المهام عند تدمير Activity\n    }\n}
\n

لاحظ: نستخدم Dispatchers.Main للعمل مع واجهة المستخدم. وتأكد من إلغاء scope في onDestroy() لتجنب تسرب الذاكرة.

\n\n

الطريقة 2: Handler و postDelayed() (كلاسيك Android)

\n

إذا كنت تكتب لتطبيق Android ولا تريد (أو لا تستطيع) استخدام coroutines، فإن Handler القديم الجيد لا يزال يعمل. كانت هذه الطريقة شائعة قبل عصر coroutines.

\n
import android.os.Bundle\nimport android.os.Handler\nimport android.os.Looper\nimport androidx.appcompat.app.AppCompatActivity\n\nclass MainActivity : AppCompatActivity() {\n\n    private val handler = Handler(Looper.getMainLooper())\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        setContentView(R.layout.activity_main)                

المدونات

توصيات الكتب