كيف تجعل تطبيقك أسرع وأكثر كفاءة باستخدام LaunchedEffect و SideEffect

تسريع التطبيقات باستخدام LaunchedEffect و SideEffect
تحسين أداء تطبيقاتك بـ LaunchedEffect و SideEffect

أسرار تحسين أداء تطبيقاتك باستخدام LaunchedEffect و SideEffect

في عالم تطوير البرمجيات ، خاصة مع تطور تطبيقات الاندرويد والأطر مثل Kotlin Compose، أصبح فهم كيفية التعامل مع الآثار الجانبية أمرًا ضروريًا لأي مطور يريد إنشاء تطبيقات فعالة ومستقرة. يلعب مديرو التأثيرات (LaunchedEffect) دورًا مركزيًا في التحكم في هذه الآثار الجانبية، مما يتيح بضبط أفضل وأداء أعلى.للتطبيقات. في هذه المقالة، سنبحر معكم في مدير التأثيرات في Kotlin Compose، مع التركيز على كيفية استخدامها وأهميتها وأنماط استخدامها المختلفة.


ما هي معالجات التأثير في Kotlin Compose؟

معالجات التأثير في Kotlin Compose هي أدوات تُستخدم للتعامل مع العمليات الثانوية التي تقع خارج نطاق واجهة المستخدم. وتشمل هذه من المكون. الثانوية مثل طلبات الشبكة وقراءة البيانات وكتابتها ومعالجة الملفات وتسمى أيضًا واجهات البرمجة. تحدث هذه التأثيرات بشكل غير متزامن ويتم التحكم فيهاخارج السياق الرئيسي للمركبات ( يمكنك الوصول اليها من خارج التصميم ).


مفهوم Effect Handlers في Kotlin Compose

في إطار عمل Kotlin Compose، تعد العمليات الجانبية جزءًا من إنشاء التطبيقات التفاعلية. قد تشمل العمليات الثانوية ما يلي:

  • استدعاء API: الحصول على البيانات من الخادم.تفاعل النظام: مثل طلبات الأذونات.
  • التخزين المحلي: كتابة وقراءة البيانات من الذاكرة المحلية. 
  • التوقيت: استخدم المؤقتات أو المهام المؤقتة.


لماذا نحتاج إلى مدير التأثير (LaunchedEffect) في تطبيقاتنا ؟

تسمح لك معالجات التأثير في Kotlin Compose بفصل التأثيرات الجانبية عن منطق واجهة المستخدم الرئيسي. يتيح لك ذلك إنشاء تطبيقات مرنة وقابلة للصيانة وأكثر كفاءة. يعتمد Kotlin Compose على دورة حياته التي تسمح بإعادة تركيب المكونات عدة مرات، ومن هنا تأتي الحاجة إلى استخدام مديري التأثير لضمان تنفيذالآثار الجانبية في الوقت المناسب ووفقا لشروط التطبيق.


اقسام SideEffect

Suspended :

  1. LaunchedEffect
  2. rememberCoroutineScope


Non-suspended :

  1. DisposableEffect
  2. SideEffect

 التأثيرات في Kotlin Compose LaunchedEffect

LaunchedEffect الأكثر استخدامًا في Kotlin Compose ويستخدم لتنفيذ العمليات غير المتزامنة المتعلقة بواجهة المستخدم. يتم تنفيذه مرة واحدة أثناء التثبيت أو عندما تتغير القيم المحددة .
@Composable
fun MyComposable(data: String) {
    LaunchedEffect(data) {
        // يقوم بتنفيذ العملية الجانبية مرة واحدة أو عند تغير data
        fetchDataFromApi(data)
    }

    Text("Data: $data")
}
في هذا المثال، يتم استدعاء fetchDataFromApi لاسترداد البيانات عند تشغيل الclass المكون أو عند تغيير قيمة البيانات (عندما تتغير قيمة data يتم الحصول على البيانات وطبعا فهي تعمل عند عمل التطبيق لاول مره فقط)
remember هو معالج تأثير آخر يُستخدم لتذكر قيمة أو كائن أثناء دورة حياة مكون معين، ولكنه يعمل فقط عند إعادة تكوينه.
@Composable
fun Counter() {
    var count by remember { mutableStateOf(0) }

    Button(onClick = { count++ }) {
        Text("Count: $count")
    }
}
في هذا المثال، يتم تذكر قيمة العدد باستخدام تذكر ولا يتم فقدان قيمتها حتى عند إعادة تكوين المكون (rememberCoroutineScop)
يسمح لك RememberCoroutineScope بفتح coroutine مرتبط بعمر المكون.

@Composable
fun MyComposable() {
    val scope = rememberCoroutineScope()

    Button(onClick = {
        scope.launch {
            // تشغيل عملية غير متزامنة
            delay(1000)
            println("Button clicked after delay")
        }
    }) {
        Text("Click Me")
    }
}
rememberCoroutineScope يستخدم لتنفيذ العمليه داخل هذا ال Composable فقط ولا يعمل على مستوى التطبيق

DisposableEffect
DisposableEffect يُستخدم عندما تحتاج إلى تشغيل عملية ثانوية، ولكنك تحتاج أيضًا إلى تنظيف تلك العملية عند التخلص من المكون.
@Composable
fun MyDisposableEffect() {
    DisposableEffect(Unit) {
        // تنفيذ التأثير الجانبي
        println("Effect started")

        onDispose {
            // تنظيف العملية عند إزالة المكون
            println("Effect ended")
        }
    }

    Text("DisposableEffect Example")
}
في هذا المقال يتم تشغيل عملية وعند الانتهاء منها يتم التخلص منها ومن موقعها في الذاكره بعد الانتهاء منها

متى نستخدم DisposableEffect ؟

عندما تحتاج إلى تنظيف الموارد بعد استخدام عملية ثانوية، مثل إلغاء الاشتراك أو إيقاف التشغيل أو إلغاء مكالمة شبكة.عندما تحتاج إلى التفاعل مع دورة حياة أحد المكونات والتأكد من معالجة الآثار الجانبية بشكل صحيح عند إزالة المكون.
مثال تطبيقي حول استخدام SideEffect في كوتلن كومبوس
@Composable
fun DataFetcherScreen() {
    var data by remember { mutableStateOf("Loading...") }
    val scope = rememberCoroutineScope()

    LaunchedEffect(Unit) {
        try {
            data = fetchDataFromApi()
        } catch (e: Exception) {
            data = "Error loading data"
        }
    }

    DisposableEffect(Unit) {
        onDispose {
            println("Screen disposed")
        }
    }

    Column {
        Text("Data: $data")

        Button(onClick = {
            scope.launch {
                data = "Loading..."
                data = fetchDataFromApi()
            }
        }) {
            Text("Refresh Data")
        }
    }
}

suspend fun fetchDataFromApi(): String {
    delay(1000)  // محاكاة التأخير
    return "Data loaded from API"
}
متى يجب استخدام RememberCoroutineScope بدلاً من LaunchedEffect؟ يستخدم عندما نحتاج إلى إطلاق كوروتين يتعلق بدورة حياة المكون ويتم إطلاقه تلقائيًا عند تثبيت المكون أو عندما تتغير القيم التي يعتمد التأثير عليها.من ناحية أخرى، يمنحنا RememberCoroutineScope القدرة على تشغيل Coroutines يدويًا والتحكم فيها من خلال واجهة المستخدم.

يوفر مديرو التأثيرات في Kotlin Compose أداة قوية لإدارة العمليات الجانبية بطريقة منظمة وفعالة. سواء أكان ذلك يتعلق باستدعاءات واجهة برمجة التطبيقات (API)، أو الموقتات، أو العمل مع البيانات الخارجية، فإن هذه الأدوات تساعد في إنشاء تطبيقات أكثر استقرارًا وأسهل في الصيانة.

شرح انواع LaunchedEffect مع مثال لكل نوع منهم


🔥ما هو SideEffect في Jetpack Compose؟

ما هو SideEffect في Jetpack Compose


عند العمل مع Compose، يتم إعادة إنشاء واجهة المستخدم عند حدوث أي تغيير في State، مما قد يؤدي إلى تنفيذ تأثيرات جانبية غير مرغوب فيها. وهنا يأتي دور SideEffect لضمان تنفيذ التأثير الجانبي مرة واحدة فقط عند إعادة الإنشاء.
@Composable
fun SideEffectExample() {
    var count by remember { mutableStateOf(0) }

    SideEffect {
        Log.d("SideEffect", "القيمة الحالية لـ count: $count")
    }

    Button(onClick = { count++ }) {
        Text("زيادة العدد")
    }
}

🤔 ما هو LaunchedEffect ولماذا نحتاجه؟

ما هو LaunchedEffect ولماذا نحتاجه


عند الحاجة إلى تشغيل Coroutine عند بدء تشغيل Composable، فإن LaunchedEffect هو الخيار الأمثل، حيث يعمل على تشغيل المهمة فقط عند دخول Composable إلى الشجرة، ويتوقف عند خروجه.
@Composable
fun LaunchedEffectExample() {
    var text by remember { mutableStateOf("مرحبا بك!") }

    LaunchedEffect(Unit) {
        delay(3000)
        text = "تم تحديث النص بعد 3 ثواني!"
    }

    Text(text = text)
}

👌 متى نستخدم rememberCoroutineScope؟

متى نستخدم rememberCoroutineScope

إذا كنت بحاجة إلى تشغيل Coroutine استجابةً لحدث مثل ضغط زر، ولكنك لا تريد أن يكون مرتبطًا بإعادة بناء Composable، فإن rememberCoroutineScope هو الحل الأفضل.
@Composable
fun RememberCoroutineScopeExample() {
    val scope = rememberCoroutineScope()
    var text by remember { mutableStateOf("اضغط لبدء التحميل") }

    Button(onClick = {
        scope.launch {
            text = "جار التحميل..."
            delay(3000)
            text = "تم التحميل بنجاح!"
        }
    }) {
        Text(text = text)
    }
}

🙏 متى نستخدم DisposableEffect ؟

متى نستخدم DisposableEffect

DisposableEffect هو أحد الأدوات القوية في Jetpack Compose مُصمم لإدارة العمليات التي تتطلب تنظيفًا تلقائيًا عند مغادرة الشاشة أو تغيير التبعيات (Dependencies). على عكس LaunchedEffect الذي يركز على تنفيذ العمليات مرة واحدة، يركز DisposableEffect على ضمان إيقاف المهام المستهلكة للموارد (مثل الحساسات، الاتصالات الشبكية) عند عدم الحاجة إليها، مما يحسن كفاءة التطبيق ويحمي بطارية الجهاز.
@Composable
fun CompassScreen(sensorManager: SensorManager) {
    val sensor = remember { sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION) }
    val sensorEventListener = remember {
        object : SensorEventListener {
            override fun onSensorChanged(event: SensorEvent?) {
                event?.let {
                    // تلتزمُ يتعرض هنا البيانات المستخدم
                    println("تأوية اليومًلة: ${event.values[0]}")
                }
            }

            override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {}
        }
    }

    DisposableEffect(sensor) {
        // الكيميوليا يتصل أول مرة. فبدأ تستمع الحساس لا
        sensorManager.registerListener(sensorEventListener, sensor, SensorManager.SENSOR_DELAY_UI)

        onDispose {
            // "ده مستندًا لنا الكيميوليا بخرج أو لو حصل تغيير في" sensor"
            sensorManager.unregisterListener(sensorEventListener)
            println("إيقاف الحساس")
        }
    }

    // راجعة المستخدم
    Text(text = "الشاشة يتعرض بيانات اليومًلة")
}
تعليقات