You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose页面进入时如何从网络或数据库加载数据

解决方案

你要实现的两个功能都可以通过Compose官方提供的LaunchedEffect完成,这是官方推荐的标准方案,实现逻辑非常简单,不存在额外复杂度。

第一步:修正状态声明

你原来的json是普通Kotlin变量,值修改后不会触发Compose重组,界面不会同步更新,首先需要修改为可观察状态:

// 先导入依赖
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.runtime.LaunchedEffect
import kotlinx.coroutines.delay
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@Composable
fun DemoScreen(navController: NavController) {
    // 改为可观察状态,修改后自动触发界面更新
    var json by remember { mutableStateOf("Placeholder content, to be updated on screen load and refreshed every x seconds...") }
    // 可选:加载状态,用来控制进度提示显示
    var isLoading by remember { mutableStateOf(false) }

第二步:实现进入页面自动加载+定时刷新

直接在函数内添加LaunchedEffect代码块即可,它会和当前Composable的生命周期绑定,页面退出时内部协程自动取消,不会产生内存泄漏:

// key设为Unit表示仅在当前页面首次进入时执行一次,页面重建、普通重组都不会重复触发
    LaunchedEffect(Unit) {
        // 首次进入先执行一次加载
        isLoading = true
        json = loadData()
        isLoading = false

        // 定时循环刷新,示例为30秒刷新一次,可自行调整间隔时间
        while(true) {
            delay(30 * 1000) // 时间单位为毫秒
            isLoading = true
            json = loadData()
            isLoading = false
        }
    }

    // 封装你的数据请求逻辑
    suspend fun loadData(): String {
        return withContext(Dispatchers.IO) {
            try {
                // 这里替换为你的真实API请求/数据库查询逻辑
                "请求到的新数据 ${System.currentTimeMillis()}"
            } catch (e: Exception) {
                "请求失败:${e.message}"
            }
        }
    }

第三步:可选添加加载进度提示

可以在你原有的Box布局中增加居中的加载进度条,加载状态时显示:

Box(modifier = Modifier
        .fillMaxWidth()
        .fillMaxHeight()
    ){
        // 原有Column主内容区域代码保持不变
        Column(
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.Center,
            modifier = Modifier
                .fillMaxWidth()
                .padding(horizontal = 0.dp)
        ) {
            // 原有TextField、Button代码不用修改
            TextField(
                value = json,
                onValueChange = { json = it },
                singleLine = false,
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(5.dp)
                    .height(500.dp),
                maxLines = 10,
            )
            val coroutineScope = rememberCoroutineScope()
            Button(
                onClick = {
                    coroutineScope.launch {
                        withContext(Dispatchers.IO) {
                            try {
                                //按钮点击逻辑
                            } catch (e: Exception) {
                                Log.d("button", e.message.toString())
                            } finally {
                                Log.d("button", "in finally")
                            }
                        }
                    }
                },
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(5.dp)
                    .height(100.dp)
            ) {
                Text(text = "Demo Button")
            }
        }

        // 新增:加载时显示进度条
        if (isLoading) {
            CircularProgressIndicator(modifier = Modifier.align(Alignment.Center))
        }
    }
}

说明

如果后续需要根据页面入参变化重新加载数据,只需要把LaunchedEffect的key从Unit改为对应的参数即可,参数变化时会自动取消旧的协程,执行新的加载逻辑。

内容的提问来源于stack exchange,提问作者Pawan Pillai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.08 11:30:01