Похоже, согласно документации ProcessLifecycleOwner, это должно быть довольно просто.
Это полезно для случаев, когда вы хотите отреагировать когда ваше приложение переходит на передний план или переходит в фоновый режим, и вам не нужна точность в миллисекундах для получения событий жизненного цикла.
Поэтому мы реализовали это следующим образом: код ниже. Функция предварительной загрузки фактически запускает службу.
Код: Выделить всё
suspend fun preloadInForeground(
lifecycleOwner: LifecycleOwner = ProcessLifecycleOwner.get(),
) {
lifecycleOwner.withStateAtLeast(Lifecycle.State.STARTED) {
preload()
}
}
Код: Выделить всё
DownloadService
.sendAddDownload(context, MyAppDownloadService::class.java, downloadRequest, /* foreground= */ false)
Код: Выделить всё
android.app.BackgroundServiceStartNotAllowedException: Not allowed to start service Intent { act=androidx.media3.exoplayer.downloadService.action.ADD_DOWNLOAD cmp=**OMITTED** (has extras) }: app is in background uid UidRecord{X Y TPSL idle change:procstateprocadj procs:0 seq(Z,ZZ)}
at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1918)
at android.app.ContextImpl.startService(ContextImpl.java:1874)
at android.content.ContextWrapper.startService(ContextWrapper.java:827)
at androidx.media3.exoplayer.offline.DownloadService.startService(DownloadService:874)
at androidx.media3.exoplayer.offline.DownloadService.sendAddDownload(DownloadService:432)
at **OMITTED**.preload(**OMITTED**:43)
... *********** APP CODE OMITTED
kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(BaseContinuationImpl:33)
at kotlinx.coroutines.internal.DispatchedContinuation.resumeUndispatchedWith$kotlinx_coroutines_core(DispatchedContinuation:252)
at kotlinx.coroutines.internal.DispatchedContinuationKt.resumeCancellableWith(DispatchedContinuationKt:278)
at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable(CancellableKt:26)
at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable$default(CancellableKt:21)
at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart:88)
at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine:123)
at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch(BuildersKt__Builders_commonKt:52)
at kotlinx.coroutines.BuildersKt.launch(BuildersKt:1)
at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch$default(BuildersKt__Builders_commonKt:43)
at kotlinx.coroutines.BuildersKt.launch$default(BuildersKt:1)
at
... *********** APP CODE OMITTED
at androidx.lifecycle.WithLifecycleStateKt$suspendWithStateAtLeastUnchecked$2$observer$1.onStateChanged(WithLifecycleStateKt:182)
at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry:314)
at androidx.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry:251)
at androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry:287)
at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry:136)
at androidx.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry:119)
at androidx.lifecycle.ReportFragment$Companion.dispatch$lifecycle_runtime_release(ReportFragment:192)
at androidx.lifecycle.ReportFragment$LifecycleCallbacks.onActivityPostStarted(ReportFragment:121)
at android.app.Activity.dispatchActivityPostStarted(Activity.java:1520)
at android.app.Activity.performStart(Activity.java:8662)
at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3945)
at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221)
at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2426)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:211)
at android.os.Looper.loop(Looper.java:300)
at android.app.ActivityThread.main(ActivityThread.java:8503)
at java.lang.reflect.Method.invoke(Method.java:-2)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:561)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:954)
Альтернативой было бы просто перехватить и проглотить исключение, но это будет означать, что служба иногда не запустится (т. е. приложит максимум усилий). Это могло бы подойти для нашего варианта использования, но хотелось бы по возможности этого избежать.
Подробнее здесь: https://stackoverflow.com/questions/790 ... foreground