我建议将其委托给 Worker 来处理此任务。真正了解这项工作的内容并不是您的活动责任;如果您的活动被破坏/重新创建,这项工作将重新开始。
参考:Android WorkManager
和Coroutine Worker
您还可以使用 Android 的 LifecycleObserver 来确保这项工作仅在应用程序处于前台时执行。这里有一个快速示例:
您的应用程序类
class MyApp: Application(), LifecycleObserver {
companion object {
private var isAppForeground = true
@Synchronized
fun isAppInForeground(): Boolean = isAppForeground
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
private fun onAppBackground() {
// Each time our app goes into the background this function
// will be called. Set the static boolean variable to false.
isAppForeground = false
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
private fun onAppForeground() {
// Each time our app comes into the foreground this function
// will be called. Set the static boolean variable to true.
isAppForeground = true
}
}
您的自定义工作人员
class MyWorker(
context: Context,
workerParams: WorkerParameters
) : CoroutineWorker(context, workerParams) {
companion object {
const val WORK_TAG = "MyWorkerTag"
}
override suspend fun doWork(): Result {
if (MyApp.isAppInForeground) {
// Do your work here that you want to repeat.
// You can return either Result.success()
// Result.failure()
// of Result.retry() if you want to retry this specific instance.
} else {
return Result.failure()
}
}
}
MainActivity
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
initWorker()
}
private fun initWorker() {
val workManager = WorkManager.getInstance(this)
/* You can define whatever constraints are required for this
work to run. Here I have just set a constraint that the device
must have a valid network connection. Useful if your work will
require API calls or upload / downloading data */
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
/* Work can be scheduled on whatever repeating interval you define, with a
minimum being every 15 minutes. */
val myWorkRequest = PeriodicWorkRequestBuilder<MyWorker>(
repeatInterval = 15L,
repeatIntervalTimeUnit = TimeUnit.MINUTES
).setConstraints(constraints).build()
/* You can define the existing work policy when enqueueing the work, to determine
what will happen the next time this code is run. You can either REPLACE
the existing scheduled work or KEEP the existing work. */
workManager.enqueueUniquePeriodicWork(
MyWorker.WORK_TAG,
ExistingPeriodicWorkPolicy.REPLACE,
myWorkRequest
)
}