Jetpack Compose中的副作用的使用

本文作者系360奇舞团前端开发工程师

什么是副作用?

副作用是指在函数式编程和声明式UI框架中,那些在函数执行过程中除了返回结果之外还产生的其他影响或操作。在Jetpack Compose这样的声明式UI框架中,副作用通常指的是那些在Composable函数中执行的操作,这些操作会在每次Composable函数被重新计算时执行,而不是只在函数首次调用时执行。这与命令式编程中的副作用有所不同,后者通常指的是在函数执行过程中改变全局状态或产生外部影响。

为什么需要管理副作用?

在Jetpack Compose这样的声明式UI框架中,管理副作用至关重要。首先,它符合声明式编程模型的要求,即界面通过函数的反复执行来渲染。其次,管理副作用可以优化性能和资源利用,避免不必要的UI重组和计算。例如,如果不正确地管理网络请求或事件监听器的注册和注销,可能会导致性能下降或资源泄漏。因此,了解如何正确使用副作用API是构建高效、可维护应用的关键。

Jetpack Compose 中的副作用 API

LaunchedEffect

定义:LaunchedEffect 用于在 Composable 中启动一个协程。它在指定的key变化时重新启动,并可以执行异步操作。

使用场景:

当数据变化时,需要进行一些操作,比如网络请求,数据更新等

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import kotlinx.coroutines.delay
import androidx.compose.material.Button
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp


@Composable
fun LaunchedEffectDemo() {
    var count by remember { mutableStateOf(0) }
    var result by remember { mutableStateOf(0) }

    //第一次加载的时候也会执行一次
    LaunchedEffect(count) {
        println("发生了变化")
        // 在这里可以做网络请求
        delay(1000)
        result++;

    }

    Column(horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.padding(top=80.dp)) {
        Text(text = "Count: "+count+"  result="+result)
        Button(onClick = { count++ }) {
            Text("加")
        }
    }
}

关键点:

  • 适合用于处理与状态变化直接相关的副作用。

  • 每次键值变化时会启动新的协程,之前的协程会被取消。

rememberCoroutineScope

定义:rememberCoroutineScope 返回一个 CoroutineScope,它可以在 Composable 中启动新的协程。适合在用户交互时使用。直译的话就是记住协程区域

使用场景:

异步操作:当需要在 Compose 组件中执行异步操作时(如网络请求、文件读写等),可以使用 rememberCoroutineScope 来启动协程。

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import kotlinx.coroutines.delay
import androidx.compose.material.Button
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.launch

@Composable
fun CoroutineScopeDemo() {
    val coroutineScope = rememberCoroutineScope() // 创建协程作用域
    var count by remember { mutableStateOf(0) }
    var result by remember { mutableStateOf(0) }


    Column(horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.padding(top=80.dp)) {
        Text(text = "Count: "+count+"  result="+result)
        Button(onClick = {
            coroutineScope.launch {
                delay(1000) // 模拟延迟
                result++ // 更新状态
            }
        }) {
            Text("点击")
        }
    }
}

关键点:

rememberCoroutineScope 提供了一个方便的方式来在用户交互时启动协程,确保在 UI 线程之外执行耗时操作。

SideEffect

定义:SideEffect 用于在每次重组时执行副作用。它适合记录日志、调试信息等,而不依赖于特定的状态变化。

使用场景:

调试信息的记录:在每次重组时输出状态,有助于调试 更新某个外部状态而不影响 UI。

import androidx.compose.foundation.layout.Column
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable

import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment

import androidx.compose.material.Button
import androidx.compose.runtime.SideEffect

@Composable
fun SideEffectDemo() {
    var count by remember { mutableStateOf(0) }

    SideEffect {
        // 每次重组时都会执行这个块
        println(" -------count: $count") // 打印当前计数
    }

    Column(horizontalAlignment = Alignment.CenterHorizontally) {
        Text(text = "Count: $count")
        Button(onClick = { count++ }) {
            Text("点击")
        }
    }
}

关键点:

  • SideEffect 在每次重组时执行,适合用于需要执行的副作用。

  • 它不依赖于任何状态,因此在多个状态变化时也会被调用。

DisposableEffect

定义:DisposableEffect 用于在 Composable 退出时执行清理操作,例如解除注册、释放资源。

使用场景:

资源的清理:如取消网络请求、解除事件监听。确保不再需要的资源在 Composable 退出时被正确释放。

import android.content.Context
import android.hardware.Sensor
import android.hardware.SensorEvent
import android.hardware.SensorEventListener
import android.hardware.SensorManager
import androidx.compose.foundation.layout.fillMaxSize

import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.runtime.DisposableEffect
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
@Composable
fun DisposableEffectDemo() {
    val context = LocalContext.current
    var sensorData by remember { mutableStateOf("无数据") }

    DisposableEffect(Unit) {
        // 获取传感器管理器
        val sensorManager = context.getSystemService(Context.SENSOR_SERVICE) as SensorManager
        val sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)

        // 创建传感器事件监听器
        val sensorEventListener = object : SensorEventListener {
            override fun onSensorChanged(event: SensorEvent) {
                // 更新传感器数据
                sensorData = "X: ${event.values[0]}, Y: ${event.values[1]}, Z: ${event.values[2]}"
            }

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

            }
        }

        // 注册监听器
        sensorManager.registerListener(sensorEventListener, sensor, SensorManager.SENSOR_DELAY_NORMAL)

        // 清理代码
        onDispose {
            // 注销监听器
            sensorManager.unregisterListener(sensorEventListener)
        }
    }

    // 组件的 UI 逻辑
    Text(
        text = sensorData,
        modifier = Modifier.fillMaxSize()
    )
}

关键点:

  • 通过 onDispose,可以确保在组件生命周期结束时执行必要的清理,防止内存泄漏,可以确保资源被正确管理,不再需要时释放。

总结

掌握Jetpack Compose的副作用管理,能显著提升应用性能与可维护性。正确使用API,让状态、资源与用户交互处理更顺畅,优化用户体验。在现代UI框架中,副作用管理至关重要,掌握它,让应用设计更出色,实现更高效。

- END -

如果您关注前端+AI 相关领域可以扫码进群交流

 f507e4653cfe81b63cfc63cfddc4a50d.jpeg

添加小编微信进群😊

关于奇舞团

奇舞团是 360 集团最大的大前端团队,非常重视人才培养,有工程师、讲师、翻译官、业务接口人、团队 Leader 等多种发展方向供员工选择,并辅以提供相应的技术力、专业力、通用力、领导力等培训课程。奇舞团以开放和求贤的心态欢迎各种优秀人才关注和加入奇舞团。

35a7cfb955c33506d544a1d5ac299a5d.png

智慧档案馆建设方案旨在通过先进的信息技术和智能化手段,全面提升档案管理的效率和安全性,满足现代档案管理的需求。方案涵盖了软件、硬件、网络及安全、分布式存储、数据保护、机房建设等多个方面,确保档案馆在数字化、智能化转型中具备高效、安全、可扩展的能力。 在软件部分,智慧档案馆平台集成了档案接收、管理、保存、智能库房管理、辅助鉴定、编研、统计、内部利用、电子阅览室智能服务等功能模块。通过智能化的档案接收和管理流程,系统能够高效处理各类档案数据,支持历史数据迁移、数字化成果接收、征集档案接收等操作。智能库房管理模块通过虚拟库房、调卷归卷管理、温湿度管理等功能,确保实体档案的安全保管和高效利用。此外,系统还提供了智能辅助鉴定、编研、统计等功能,帮助档案馆实现档案的智能化管理和利用。 硬件部分则包括网络及安全设备、分布式存储、数据保护一体机、离线备份设备、机房建设等。网络及安全设备如核心交换机、汇聚交换机、下一代防火墙、终端安全管理系统等,确保了档案馆网络的高效运行和数据的安全防护。分布式存储系统通过全分布式架构和数据冗余技术,提供了高可伸缩性和高可用性,支持多副本或EC冗余机制,确保数据的安全性和快速重构。数据保护一体机和离线备份设备则通过多种备份和恢复机制,确保数据的完整性和可恢复性。机房建设部分则通过UPS、精密配电柜、精密空调、冷通道机柜等设备,确保机房的稳定运行和高效管理。 智慧档案馆建设方案不仅顺应了国家档案信息化建设的政策要求,还结合了云计算、区块链等新技术,确保了系统的先进性和安全性。通过智能化的档案管理和高效的数据保护机制,档案馆能够更好地服务于公众,提升档案利用效率,实现档案资源的共建共享。这一方案不仅是档案数字化转型的重要举措,也为未来档案馆的智能化发展奠定了坚实基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值