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

3
在我的应用程序中,我启动了一个WebSocketWorker任务,每15分钟定期运行一次。正如名称所示,它包含一个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用于输入消息,以及一个带有setOnClickListener的Button来发送消息,就像这样:

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 objects”翻译为“数据对象”,“worker”翻译为“工作者”或“任务处理器”)

1个回答

2
我的经验告诉我可以做到。基本上,你不能通过API与worker对象进行交互,这真的很烦人。
例如,在JS中,您可以选择获取作业并检查作业的参数。但是在work中没有这样的选项。例如,我想检查限制的当前状态-什么满足,什么不满足。没有类似的东西。您只能检查状态、取消等等。
我的建议是因为WorkManager是其他库(如JS)的“外观/适配器”。它有自己的数据库,以便在设备重新启动时恢复JS作业等等,但除此之外,如果您想与内部交互,我想他们只是觉得太复杂了,所以跳过了。
您只需注入其他对象,每次工作时都可以向其请求数据。我看不到其他选择。

是的,这确实很烦人。但感谢您的回答。 - abdullah celik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接