我有一个定期执行的Worker。它连接到BLE设备并从该设备同步数据。连接是由观察者完成的。调用syncRides()的doWork。syncRides创建一个observeForever,并在建立连接时启动连接,调用BleClient.runBleSync()。
我担心的是每隔15分钟调用一次的" observeForever“(最短的WorkManager时间),并创建未删除的observeForever。问题是BleWorker没有LifecycleOwner来创建"BleClient.connectionStatus.observe“而不是"BleClient.connectionStatus.observeForever”。我的问题是,我是否应该关注使用observeForever并每15分钟触发一次。或者你可以建议更好的选项,比如添加和删除观察者。
此外,在没有GlobalScope.launch(Dispatchers.Main)的情况下运行时,会出现此函数无法在后台线程上运行的错误。那么当在Worker中运行时,Dispatchers.Main意味着什么呢?
class BleWorker(appContext: Context, workerParams: WorkerParameters) : CoroutineWorker(appContext, workerParams) {
override suspend fun doWork(): Result {
return try {
try {
RLog.d("Run work manager")
syncRides()
val output: Data = workDataOf("KEY_RESULT" to 1)
Result.success(output)
} catch (e: Exception) {
RLog.d("exception in doWork ${e.message}")
Result.failure()
}
} catch (e: Exception) {
RLog.d("exception in doWork ${e.message}")
Result.failure()
}
}
private suspend fun syncRides() {
GlobalScope.launch(Dispatchers.Main) {
val bleDevice = SharedPreferenceHelper.getBleMac()
if (bleDevice != null && BleClient.connectionStatus.value == BleClient.ConnectionStatus.NOT_CONNECTED) {
BleClient.connect(bleDevice)
}
BleClient.connectionStatus.observeForever {
RLog.d("Observing $it")
when (it) {
BleClient.ConnectionStatus.CONNECTED -> {
GlobalScope.launch(Dispatchers.IO) {
RLog.d("Running sync")
BleClient.runBleSync()
}
}
else -> {
RLog.d("No status")
}
}
}
}
}BleClient:
object BleClient {
val connectionStatus = MutableLiveData(ConnectionStatus.NOT_CONNECTED)
fun connect(mac: String) {
//do some magic
connectionStatus.postValue(ConnectionStatus.CONNECTED)
}
}发布于 2021-08-09 15:23:23
我假设应用程序连接到蓝牙上的另一个设备上的任何同步数据.如果我的假设是正确的,首先,您应该将同步过程卸载到前台服务,因为该过程将花费很长时间。不过,您仍然可以使用WorkManager进行调度。在前台服务中,您应该连接BLE和同步数据。为此,有不同的选择。如果您需要使用observable来观察连接状态,则应该使用MutableSharedFlow而不是MutableLiveData,这样您就可以观察在Service类中创建的生命周期范围内的更改。然而,在我看来,更好的做法是将connect()函数转换为可挂起的函数。为此,您可以使用suspendCoroutine构建器进行转换。另外,如果你同时从不同的线程调用connect函数,你必须使用lock来避免多个连接。Kotlin Coroutines为此提供了非阻塞锁。在将connect()函数转换为suspend函数之后,您可以以线性方式实现您的逻辑,这很容易,并且不需要任何类型的观察。
https://stackoverflow.com/questions/68608561
复制相似问题