Android WorkManager - 我可以将输入数据传递给定期运行的 Worker 吗?

Posted

技术标签:

【中文标题】Android WorkManager - 我可以将输入数据传递给定期运行的 Worker 吗?【英文标题】:Android WorkManager - Can I pass input data to a Worker that runs periodically? 【发布时间】:2021-09-06 14:41:08 【问题描述】:

在我的应用程序中,我启动了一个每 15 分钟定期运行的 WebSocketWorker 任务。顾名思义,它包含一个用于在后台监听套接字的WebSocket:

// MainApplication.kt
override fun onCreate() 
        super.onCreate()
        if (BuildConfig.DEBUG) 
            Timber.plant(DebugTree())
        

        val work = PeriodicWorkRequestBuilder<WebSocketWorker>(15, TimeUnit.MINUTES).build()
        workManager.enqueueUniquePeriodicWork("UniqueWebSocketWorker", ExistingPeriodicWorkPolicy.KEEP, work)
    

WebSocketWorker 包含以下逻辑:

@HiltWorker
class WebSocketWorker  @AssistedInject constructor(
    @Assisted appContext: Context,
    @Assisted workerParams: WorkerParameters
) : CoroutineWorker(appContext, workerParams) 

    inner class MyWebSocketListener : WebSocketListener() 
        override fun onMessage(webSocket: WebSocket, text: String) 
            Timber.d("The message sent is %s", text)
            // do sth. with the message 
        

        override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) 
            t.localizedMessage?.let  Timber.e("onFailure: %s", it) 
            response?.message?.let  Timber.e("onFailure: %s", it) 
        
    


    override suspend fun doWork(): Result 
        try
            // code to be executed
            val request = Request.Builder().url("ws://***.***.**.***:8000/ws/chat/lobby/").build()
            val myWebSocketListener = MyWebSocketListener()
            val client = OkHttpClient()
            client.newWebSocket(request, myWebSocketListener)
            return Result.success()
        
        catch (throwable:Throwable)
            Timber.e("There is a failure")
            Timber.e("throwable.localizedMessage: %s", throwable.localizedMessage)
            // clean up and log
            return Result.failure()
        
    


如您所见,在 Worker 类中我设置了 WebSocket,一切都很好。监听套接字工作。

现在,我还想在我的应用中添加“发送消息”功能。如何重用在WebSocketWorker 中创建的 websocket?我可以将输入数据传递给在后台运行的WebSocketWorker 吗?

假设我有一个EditText 用于输入消息,一个Button 用于发送带有 setOnClickListener 的消息,如下所示:

binding.sendButton.setOnClickListener 
            // get message
            val message = binding.chatMessageEditText.text.toString()
            // check if not empty
            if(message.isNotEmpty()) 
                
                // HOW CAN I REUSE THE WEBSOCKET RUNNING PERIODICALLY IN THE BACKGROUND?
                // CAN I PASS THE MESSAGE TO THAT WEBSOCKET ?
                // OR SHOULD I CREATE A DIFFERENT WORKER FOR SENDING MESSAGES (e.g.: a OneTimeRequest<SendMessageWorker> for sending messages ? 
            
            
        

从文档中,我知道您需要构建 Data 对象以传递输入等,但没有示例展示如何将输入传递给在后台定期运行的工作人员。

【问题讨论】:

【参考方案1】:

我的经验是你可以。基本上你“不能”通过 API 与工作对象交互。真的很烦。

例如,使用 JS,您可以选择获取作业并检查作业的参数。作品没有这样的选择。例如,我想检查限制的当前状态是什么——什么是满足的,什么是不满足的。没有这样的。你可以只检查状态,取消,这几乎是全部。

我的建议是因为 WorkManager 是 JS 等其他库的“外观/适配器”。它有自己的数据库来在设备重启时恢复 JS 作业和类似的东西,但除此之外,如果你想与内部交互,我想这对他们来说太复杂了,所以他们只是跳过了。

您可以只注入一些其他对象,并且每次工作都可以要求它提供数据。我没有看到其他选项。

【讨论】:

是的,真的很烦人。不过谢谢你的回答。

以上是关于Android WorkManager - 我可以将输入数据传递给定期运行的 Worker 吗?的主要内容,如果未能解决你的问题,请参考以下文章

Android WorkManager - 我可以将输入数据传递给定期运行的 Worker 吗?

是否可以在 google play 中发布应用程序,哪个应用程序使用了 Android 的 alpha 版本组件?喜欢 WorkManager

在 Android 12 中使用 WorkManager

Android Jetpack之WorkManager源码分析

Android Jetpack WorkManager 介绍

用于在后台运行日常任务的 Android WorkManager api