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

如何在基于Jetpack Compose的安卓钱包中自动检测支付完成

交易状态自动同步方案(Jetpack Compose + Kotlin)

针对你用固定10秒轮询获取交易状态的痛点,推荐以下几种更高效的实现方式,适配Jetpack Compose的状态管理体系:

1. 服务器主动推送(Webhook + 消息推送)

这是最优解,完全替代轮询。让后端在交易状态变更时,主动向你的App推送状态更新:

  • 集成FCM或者自定义推送服务,后端通过推送渠道发送交易状态变更通知。
  • 在App的推送接收器中解析状态数据,更新本地交易记录,同时通过StateFlow将状态同步到Compose UI。
  • ViewModel层示例代码:
class TransactionViewModel : ViewModel() {
    private val _transactionState = MutableStateFlow<TransactionState>(TransactionState.Loading)
    val transactionState: StateFlow<TransactionState> = _transactionState

    // 接收推送后的状态更新
    fun updateTransactionState(newState: TransactionState) {
        _transactionState.value = newState
    }
}
  • Compose UI层通过collectAsState()自动响应状态变化:
@Composable
fun TransactionStatusScreen(viewModel: TransactionViewModel = viewModel()) {
    val state by viewModel.transactionState.collectAsState()
    when(state) {
        is TransactionState.Success -> Text("交易成功")
        is TransactionState.Failed -> Text("交易失败")
        TransactionState.Loading -> CircularProgressIndicator()
    }
}

2. WebSocket长连接

保持App与服务器的实时双向连接,交易状态变化时服务器主动推送消息:

  • 用OkHttp实现WebSocket客户端,在ViewModel中管理连接生命周期,避免内存泄漏。
  • 将收到的状态更新通过StateFlow传递给UI层,同时处理连接断开后的重连逻辑。
  • 核心代码示例:
class TransactionViewModel : ViewModel() {
    private val _transactionState = MutableStateFlow<TransactionState>(TransactionState.Loading)
    val transactionState: StateFlow<TransactionState> = _transactionState
    private var webSocket: WebSocket? = null

    fun connectWebSocket(transactionId: String) {
        val request = Request.Builder().url("wss://your-server.com/transactions/$transactionId").build()
        webSocket = OkHttpClient().newWebSocket(request, object : WebSocketListener() {
            override fun onMessage(webSocket: WebSocket, text: String) {
                val state = parseTransactionState(text) // 解析服务器返回的JSON
                viewModelScope.launch {
                    _transactionState.emit(state)
                }
            }
        })
    }

    override fun onCleared() {
        webSocket?.close(1000, "ViewModel cleared")
        super.onCleared()
    }
}

3. 优化轮询方案(迫不得已时使用)

如果暂时无法改造后端,可将固定间隔轮询改为指数退避轮询,减少无效请求:

  • 用WorkManager实现后台轮询,设置初始间隔10秒,之后每次翻倍(20s、40s...),直到获取到最终状态(成功/失败)或达到最大重试次数。
  • 在ViewModel中监听WorkManager的任务结果,更新UI状态。
  • 核心配置:
fun scheduleTransactionPoll(transactionId: String, context: Context) {
    val workRequest = PeriodicWorkRequestBuilder<PollTransactionWorker>(10, TimeUnit.SECONDS)
        .setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 10, TimeUnit.SECONDS)
        .addTag("poll_transaction_$transactionId")
        .build()
    WorkManager.getInstance(context).enqueueUniquePeriodicWork(
        "poll_transaction_$transactionId",
        ExistingPeriodicWorkPolicy.REPLACE,
        workRequest
    )
}

关键注意事项

  • 无论用哪种方案,都要确保交易状态的最终一致性:如果推送或WebSocket消息丢失,可在App启动时触发一次主动查询。
  • 在Compose中避免直接在UI层处理网络请求,所有状态更新逻辑都放在ViewModel或Repository中,保证UI的可组合性和测试性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 23:53:33