Android CoroutineScope 和 Dispatcher.IO 上的后台作业服务
Android Background Job Service on CoroutineScope and Dispatcher.IO
上下文
我正在尝试更新 Android 6 中的几个后台作业。主要目标是使后台作业完成的工作轻便且非 ui 线程阻塞。所以我决定做一些事情:
- GlobalScope 可能不是一个好主意,因为垂死的线程会终止其他线程。所以 CoroutineScope 会成功的
- 因为我需要 I/O 和完成网络工作,所以我需要一个专为这些任务设计的线程池。所以我将使用 Dispatchers.IO
- 绑定的 JobServices 的工作是为“即发即弃”而设计的。该应用程序不关心 - 所以我将启动作业而不是等待 async
的输出
代码
总而言之,我设计了以下 JobService class 作为其他人迁移或实施的模板。由于作业被搁置,class 将 return 对继承的函数为 false。
import android.app.job.JobParameters
import android.app.job.JobService
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
class TestJobService : JobService() {
override fun onStartJob(params: JobParameters?): Boolean {
CoroutineScope(Dispatchers.IO).launch {
// Fire and Forget
}
return false
}
override fun onStopJob(params: JobParameters?): Boolean {
return false
}
}
问题
如果您想回答,请使用问题编号。
- CoroutineScope 是个好主意吗?
- 我从主线程中收到错误“I/art:注意:结束时间超过纪元:”- 这令人困惑,可能表明 JobService 在 UI 上做了很多工作线。但我没有从编舞那里得到任何错误,如果 UI 遇到麻烦,通常情况下应该是这样。
- 在 JobService 函数中 return false 是个坏主意吗
当前使用的链接
https://medium.com/androiddevelopers/coroutines-on-android-part-i-getting-the-background-3e0e54d20bb
https://medium.com/androiddevelopers/coroutines-on-android-part-ii-getting-started-3bff117176dd
https://medium.com/androiddevelopers/coroutines-on-android-part-iii-real-work-2ba8a2ec2f45
https://developer.android.com/kotlin/coroutines/coroutines-adv?hl=de#coroutinescope
https://kotlinlang.org/docs/coroutines-basics.html#extract-function-refactoring
- 您对
CoroutineScope
的唯一使用是提供 IO
调度程序。就目前而言,如果在协程中完成的任何工作抛出异常,整个范围将被取消。如果您从其中启动多个协程,那可能会出现问题。如果您确实关心这一点,您还需要使用 SupervisorJob
进行设置:CoroutineScope(Dispatchers.IO) + SupervisorJob()
.
- 如果没有您的实际代码,很难确定该错误的含义。通过快速研究,如果你做了一些只应该在主线程上发生的事情(比如访问某些 Android 组件),可能会导致该错误。也许检查您的代码是否出现这些情况并将其包装在:
withContext(Dispatchers.Main) { ... }
但这只是一个猜测,没有任何实际代码。
- docs表示
onStartJob
:
The system holds a wakelock on behalf of your app as long as your job is executing. This wakelock is acquired before this method is invoked, and is not released until either you call jobFinished(android.app.job.JobParameters, boolean), or after the system invokes onStopJob(android.app.job.JobParameters) to notify your job that it is being shut down prematurely.
Returning false from this method means your job is already finished. The system's wakelock for the job will be released, and onStopJob(android.app.job.JobParameters) will not be invoked.
并且根据 wakelock docs,
A wake lock is a mechanism to indicate that your application needs to have the device stay on.
所以不,从 onStartJob
到 return false
似乎不正确,因为 JobService
不会正确维护唤醒锁。要解决此问题,您应该从该方法 return true
完成协程后,您应该调用 jobFinished
以指示作业已完成其所有工作。
对于 onStopJob
,return 值:
true to indicate to the JobManager whether you'd like to reschedule this job based on the retry criteria provided at job creation-time; or false to end the job entirely. Regardless of the value returned, your job must stop executing.
对于这种情况,很难根据您的代码段判断什么是正确的值。您应该能够根据您的用例找出哪个是正确的。在这种方法中,您应该取消之前创建的 CoroutineScope
。为此,您需要维护对范围的引用。
上下文
我正在尝试更新 Android 6 中的几个后台作业。主要目标是使后台作业完成的工作轻便且非 ui 线程阻塞。所以我决定做一些事情:
- GlobalScope 可能不是一个好主意,因为垂死的线程会终止其他线程。所以 CoroutineScope 会成功的
- 因为我需要 I/O 和完成网络工作,所以我需要一个专为这些任务设计的线程池。所以我将使用 Dispatchers.IO
- 绑定的 JobServices 的工作是为“即发即弃”而设计的。该应用程序不关心 - 所以我将启动作业而不是等待 async 的输出
代码
总而言之,我设计了以下 JobService class 作为其他人迁移或实施的模板。由于作业被搁置,class 将 return 对继承的函数为 false。
import android.app.job.JobParameters
import android.app.job.JobService
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
class TestJobService : JobService() {
override fun onStartJob(params: JobParameters?): Boolean {
CoroutineScope(Dispatchers.IO).launch {
// Fire and Forget
}
return false
}
override fun onStopJob(params: JobParameters?): Boolean {
return false
}
}
问题
如果您想回答,请使用问题编号。
- CoroutineScope 是个好主意吗?
- 我从主线程中收到错误“I/art:注意:结束时间超过纪元:”- 这令人困惑,可能表明 JobService 在 UI 上做了很多工作线。但我没有从编舞那里得到任何错误,如果 UI 遇到麻烦,通常情况下应该是这样。
- 在 JobService 函数中 return false 是个坏主意吗
当前使用的链接
https://medium.com/androiddevelopers/coroutines-on-android-part-i-getting-the-background-3e0e54d20bb https://medium.com/androiddevelopers/coroutines-on-android-part-ii-getting-started-3bff117176dd https://medium.com/androiddevelopers/coroutines-on-android-part-iii-real-work-2ba8a2ec2f45 https://developer.android.com/kotlin/coroutines/coroutines-adv?hl=de#coroutinescope https://kotlinlang.org/docs/coroutines-basics.html#extract-function-refactoring
- 您对
CoroutineScope
的唯一使用是提供IO
调度程序。就目前而言,如果在协程中完成的任何工作抛出异常,整个范围将被取消。如果您从其中启动多个协程,那可能会出现问题。如果您确实关心这一点,您还需要使用SupervisorJob
进行设置:CoroutineScope(Dispatchers.IO) + SupervisorJob()
. - 如果没有您的实际代码,很难确定该错误的含义。通过快速研究,如果你做了一些只应该在主线程上发生的事情(比如访问某些 Android 组件),可能会导致该错误。也许检查您的代码是否出现这些情况并将其包装在:
withContext(Dispatchers.Main) { ... }
但这只是一个猜测,没有任何实际代码。
- docs表示
onStartJob
:
The system holds a wakelock on behalf of your app as long as your job is executing. This wakelock is acquired before this method is invoked, and is not released until either you call jobFinished(android.app.job.JobParameters, boolean), or after the system invokes onStopJob(android.app.job.JobParameters) to notify your job that it is being shut down prematurely.
Returning false from this method means your job is already finished. The system's wakelock for the job will be released, and onStopJob(android.app.job.JobParameters) will not be invoked.
并且根据 wakelock docs,
A wake lock is a mechanism to indicate that your application needs to have the device stay on.
所以不,从 onStartJob
到 return false
似乎不正确,因为 JobService
不会正确维护唤醒锁。要解决此问题,您应该从该方法 return true
完成协程后,您应该调用 jobFinished
以指示作业已完成其所有工作。
对于 onStopJob
,return 值:
true to indicate to the JobManager whether you'd like to reschedule this job based on the retry criteria provided at job creation-time; or false to end the job entirely. Regardless of the value returned, your job must stop executing.
对于这种情况,很难根据您的代码段判断什么是正确的值。您应该能够根据您的用例找出哪个是正确的。在这种方法中,您应该取消之前创建的 CoroutineScope
。为此,您需要维护对范围的引用。