Вы в основном делаете это правильно, за исключением того, что вы должны либо использовать onResume
/ onPause
, либо onStart
/ onStop
, не смешивая две пары. onStart
и onStop
вызываются только тогда, когда ваша деятельность полностью выходит из поля зрения. Таким образом, в вашем примере, если перед вами появилось диалоговое окно из другого приложения, onStop
не будет вызвано, но onResume
будет вызвано, поэтому ваша уже запущенная служба получит несколько вызовов onStartCommand
.
Однако весь смысл Сервисов - запускать операции, которые продолжаются, когда ваше приложение не видно. Если вы этого не делаете, было бы проще написать свой собственный класс (возможно, который реализует LifecycleObserver или заимствует lifecycleScope
из Activity) для обработки фоновой работы. Тогда вам не придется иметь дело с регистрацией в манифесте и обработкой намерений.
Пример LifecycleObserver:
// lifecycle is a property of AppCompatActivity. You can instantiate this class
// from your activity.onCreate()
class MyNeworkTaskManager(lifecycle: Lifecycle): LifecycleObserver, CoroutineScope by lifecycle.coroutineScope {
init {
lifecycle.addObserver(this)
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
private fun onResume() {
startMyRequest()
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
private fun onPause() {
pauseOrCancelMyRequest()
}
// Alternatively, if you want to expose suspend functions so your activity can request
// and respond to data in a coroutine without callbacks:
suspend fun getMyData(args: String): MyData {
val results = someNetworkRequestSuspendFunction(args)
return MyData(results)
}
// Or if you want to use coroutines for your network request, but still want
// your activity to use callbacks so it doesn't have to use coroutines to call
// these functions:
fun getMyDataAsync(args: String, callback: (MyData) -> Unit) = launch {
val results = someNetworkRequestSuspendFunction(args)
callback(MyData(results))
}
}
Я сам не очень много работаю с сетями. Но какую бы библиотеку вы не использовали, вы обычно можете конвертировать обратные вызовы в сопрограммы, используя suspendCancellableCoroutine
. Для этого есть учебники.