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

Android使用WorkManager实现FCM打印场景生产者消费者模式问询

Android FCM推送串行打印的生产者/消费者模式实现问题

业务背景与核心诉求

  • 运行环境:搭载热敏打印机的专用Android设备
  • 业务要求:应用收到FCM推送通知后需即时触发收据打印
  • 现存问题:短时间收到多条推送时,现有任务处理逻辑存在缺陷,部分推送对应的收据无法打印
  • 现有打印依赖:通过调用startActivity(...)传入携带ACTION_VIEW与指定Uri的Intent,唤醒第三方开发、我方无管控权限的外部打印服务完成全流程打印,无法修改外部服务逻辑
  • 初步改造思路:采用经典生产者/消费者模式,将所有待处理的打印Intent加入任务队列,替代原有在FCMonMessageReceived(...)回调中直接调用startActivity执行打印的逻辑,需要明确消费队列的服务实现方式,保证打印任务同步串行下发。

初始WorkManager方案实现尝试

最初选型WorkManager实现队列能力(核心诉求是支持设备重启场景下队列任务不丢失、仍能正常执行),参考官方文档编写了如下实现代码:

MyFirebaseMessagingService.kt

class MyFirebaseMessagingService : FirebaseMessagingService() {
    override fun onMessageReceived(remoteMessage: RemoteMessage) {

        remoteMessage.data.isNotEmpty().let { _ ->
            try{
                val content =
                    remoteMessage.data["content"]?.let { it1 -> Json.parseToJsonElement(it1).jsonObject }
                content?.let { it ->
                    val title = it["title"]?.toString() ?: "Title example"
                    val body = it["message"]?.toString() ?: "Msg example"
                    val pushId = it["notificationId"]?.toString() ?: "42"
                    val data = it["data"]?.jsonObject                    

                    val intent = sendToPrinterIntent(data)
                    sendNotification(..., intent)

                    //startActivity(intent) //TODO 替换为生产者-消费者队列逻辑
                    PrintingWorker.enqueueWork(this, intent)
                }
            } catch (e: Exception){
                Log.d("pushMessage", "Error in json data: $e")
            }
        }
    }

    private fun sendToPrinterIntent(data: JsonObject?): Intent {
        return data?.let {            
            val body = getBody(it)
            val uri = "customschema://q?text=$body"
            return Intent(Intent.ACTION_VIEW, Uri.parse(uri))
        } ?: Intent(Intent.ACTION_VIEW, Uri.parse("customschema://q?text="))
    }

    override fun onNewToken(token: String) {
        Log.d("FCMtoken", "Refreshed token: $token")
    }

    private fun sendNotification(
        messageBody: String,
        messageTitle: String,
        pushId: Int,
        pendingIntent: Intent
    ) {
        ...
    }

}

PrintingWorker.kt

class PrintingWorker(private val appContext: Context, workerParams: WorkerParameters) :
    CoroutineWorker(appContext, workerParams) {

    override suspend fun doWork(): Result {
        //调用startActivity并等待执行完成
        return withContext(Dispatchers.IO){
           //appContext.startActivity()
           workerParams.inputData.keyValueMap.forEach {
              println("key: ${it.key} value: ${it.value}")
           }
           //setForeground()
           Result.success()
        }
    }

    override suspend fun getForegroundInfo(): ForegroundInfo {
        return try {
            ForegroundInfo(NOTIFICATION_ID,createNotification())
        } catch (e: Exception) {
            ForegroundInfo(NOTIFICATION_ID,Notification()) //示例逻辑,可忽略
        }
    }

    private fun createNotification(): Notification {
        return NotificationCompat...
    }

    companion object{
        val TAG = "PrintingWorker"
        val NOTIFICATION_ID = 4242

        fun enqueueWork(context: Context, workData: Intent) {
            
            val workRequest = OneTimeWorkRequest.Builder(PrintingWorker::class.java)
                .setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
                .setInputData(workDataOf(Pair("printingIntent",workData)))
                .build()
            WorkManager.getInstance(context).enqueue(workRequest)
        }
    }
}

当前该方案的卡点:不确定如何配置WorkManager实现已入队Intent的串行调度消费,需要可行的实现建议。

备选方案评估

补充说明:评估多套可行方案后,考虑改用Room + 前台服务(Foreground Service)的方案实现需求,具体思路为:

  1. FCM的onReceiveMessage回调收到通知时,在Room数据库对应表中新增一条待打印任务记录
  2. 启动ForegroundService,通过Flow或类似组件消费队列记录
  3. 每条记录对应的打印任务执行完成后删除对应表项,逐条串行处理任务
    需要确认两个核心问题:
  • 该Room+前台服务的方案是否比WorkManager更适配当前业务场景
  • 如果该方案适用,如何正确使用Flow(或LiveData)实现队列消费逻辑,避免出现异常执行结果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 21:30:42