Запуск службы Android только тогда, когда приложение находится на переднем планеAndroid

Форум для тех, кто программирует под Android
Ответить Пред. темаСлед. тема
Anonymous
 Запуск службы Android только тогда, когда приложение находится на переднем плане

Сообщение Anonymous »

Мы хотим запустить androidx.media3.exoplayer.offline.DownloadService как службу, не являющуюся приоритетной. Мы хотим запускать службу только в том случае, если приложение/процесс находится на переднем плане. Если приложение/процесс не находится на переднем плане, мы ожидаем получить исключение android.app.BackgroundServiceStartNotAllowedException, поэтому нам нужен способ определить, когда приложение/процесс находится на переднем плане.
Похоже, согласно документации ProcessLifecycleOwner, это должно быть довольно просто.

Это полезно для случаев, когда вы хотите отреагировать когда ваше приложение переходит на передний план или переходит в фоновый режим, и вам не нужна точность в миллисекундах для получения событий жизненного цикла.

Поэтому мы реализовали это следующим образом: код ниже. Функция предварительной загрузки фактически запускает службу.

Код: Выделить всё

    suspend fun preloadInForeground(
lifecycleOwner: LifecycleOwner = ProcessLifecycleOwner.get(),
) {
lifecycleOwner.withStateAtLeast(Lifecycle.State.STARTED) {
preload()
}
}
Код, который фактически запускает DownloadService, выглядит следующим образом:

Код: Выделить всё

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
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Android»