在我的应用程序中,我启动了一个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 ?
}
}
从文档中,我知道您需要构建数据对象来传递输入等等,但是没有示例展示如何将输入传递给在后台定期运行的worker。
发布于 2021-09-16 08:48:40
根据我的经验,你可以做到。基本上,您“不能”通过API与worker对象交互。这真的很烦人。
例如,使用JS,您可以选择获取作业并检查作业的参数。这项工作没有这样的选项。例如,我想要检查限制的当前状态-什么是满足的,什么是不满足的。不是这样的。您可以只检查状态,取消,这是几乎所有的。
我的建议是,这是因为WorkManager是其他库(如JS )的“门面/适配器”。它有自己的数据库来在设备重启时恢复JS作业等等,但除此之外,如果你想与内部交互,我猜对他们来说太复杂了,所以他们就跳过了。
你可以仅仅注入一些其他的对象,每次工作可以向它请求它的数据。我看不到其他的选择。
https://stackoverflow.com/questions/69076343
复制相似问题