v0.3.4: update WorkerScheduler.kt
This commit is contained in:
1 parent
5c992f15e6
commit
2dfa766b95
1 file changed
+26
-12
@@ -1,6 +1,7 @@
|
|||||||
package com.hotdeal.alarm.worker
|
package com.hotdeal.alarm.worker
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.util.Log
|
||||||
import androidx.work.*
|
import androidx.work.*
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
@@ -8,35 +9,40 @@ import javax.inject.Inject
|
|||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Worker 스케줄러
|
* 실시간 백그라운드 폴링 통합 스케줄러
|
||||||
*
|
*
|
||||||
* 기본 폴� 주기: 2분
|
* 1. AlarmManager (AlarmScheduler): Doze Mode에서도 사용자가 지정한 정확한 주기(1분, 2분 등)로 즉시 실행
|
||||||
* 배터리/데이터 절약을 위해 최소 2분 권장
|
* 2. WorkManager (HotDealPollingWorker): OS 백그라운드 작업 관리 및 백업 실행
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
class WorkerScheduler @Inject constructor(
|
class WorkerScheduler @Inject constructor(
|
||||||
@ApplicationContext private val context: Context
|
@ApplicationContext private val context: Context,
|
||||||
|
private val alarmScheduler: AlarmScheduler
|
||||||
) {
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
|
private const val TAG = "WorkerScheduler"
|
||||||
const val DEFAULT_INTERVAL_MINUTES = 2L
|
const val DEFAULT_INTERVAL_MINUTES = 2L
|
||||||
const val MIN_INTERVAL_MINUTES = 1L
|
const val MIN_INTERVAL_MINUTES = 1L
|
||||||
const val MAX_INTERVAL_MINUTES = 60L
|
const val MAX_INTERVAL_MINUTES = 60L
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 주기적 폴� 예약
|
* 주기적 폴링 예약 (AlarmManager + WorkManager 이중 등록)
|
||||||
* @param intervalMinutes 폴� 간격 (분) - 기본 2분
|
* @param intervalMinutes 폴링 간격 (분)
|
||||||
*/
|
*/
|
||||||
fun schedulePeriodicPolling(intervalMinutes: Long = DEFAULT_INTERVAL_MINUTES) {
|
fun schedulePeriodicPolling(intervalMinutes: Long = DEFAULT_INTERVAL_MINUTES) {
|
||||||
// 최소/최대 값 제한
|
|
||||||
val safeInterval = intervalMinutes.coerceIn(MIN_INTERVAL_MINUTES, MAX_INTERVAL_MINUTES)
|
val safeInterval = intervalMinutes.coerceIn(MIN_INTERVAL_MINUTES, MAX_INTERVAL_MINUTES)
|
||||||
|
Log.d(TAG, "주기적 폴링 예약 시작: ${safeInterval}분 간격")
|
||||||
|
|
||||||
|
// 1. AlarmManager 기반 정확한 주기 알람 예약 (Doze mode 관통)
|
||||||
|
alarmScheduler.scheduleAlarm(safeInterval)
|
||||||
|
|
||||||
|
// 2. WorkManager 기반 백업 주기 작업 예약
|
||||||
val constraints = Constraints.Builder()
|
val constraints = Constraints.Builder()
|
||||||
.setRequiredNetworkType(NetworkType.CONNECTED)
|
.setRequiredNetworkType(NetworkType.CONNECTED)
|
||||||
.setRequiresDeviceIdle(false)
|
.setRequiresDeviceIdle(false)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
// 유연한 실행 시간 (±25%)
|
|
||||||
val flexTime = (safeInterval * 0.25).toLong().coerceAtLeast(1)
|
val flexTime = (safeInterval * 0.25).toLong().coerceAtLeast(1)
|
||||||
|
|
||||||
val workRequest = PeriodicWorkRequestBuilder<HotDealPollingWorker>(
|
val workRequest = PeriodicWorkRequestBuilder<HotDealPollingWorker>(
|
||||||
@@ -60,15 +66,17 @@ class WorkerScheduler @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 한 번만 실행
|
* 즉시 1회 실행 (메인화면 진입 / 새로고침 / 알람 수신 시)
|
||||||
*/
|
*/
|
||||||
fun executeOnce() {
|
fun executeOnce() {
|
||||||
|
Log.d(TAG, "즉시 1회 스크래핑 요청 (executeOnce)")
|
||||||
val constraints = Constraints.Builder()
|
val constraints = Constraints.Builder()
|
||||||
.setRequiredNetworkType(NetworkType.CONNECTED)
|
.setRequiredNetworkType(NetworkType.CONNECTED)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
val workRequest = OneTimeWorkRequestBuilder<HotDealPollingWorker>()
|
val workRequest = OneTimeWorkRequestBuilder<HotDealPollingWorker>()
|
||||||
.setConstraints(constraints)
|
.setConstraints(constraints)
|
||||||
|
.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
|
||||||
.addTag(HotDealPollingWorker.TAG)
|
.addTag(HotDealPollingWorker.TAG)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
@@ -76,22 +84,28 @@ class WorkerScheduler @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 폴� 취소
|
* 폴링 취소
|
||||||
*/
|
*/
|
||||||
fun cancelPolling() {
|
fun cancelPolling() {
|
||||||
|
Log.d(TAG, "폴링 전체 취소")
|
||||||
|
alarmScheduler.cancelAlarm()
|
||||||
WorkManager.getInstance(context).cancelUniqueWork(HotDealPollingWorker.WORK_NAME)
|
WorkManager.getInstance(context).cancelUniqueWork(HotDealPollingWorker.WORK_NAME)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 폴� 활성화 여부 확인
|
* 폴링 활성화 여부 확인
|
||||||
*/
|
*/
|
||||||
fun isPollingActive(): Boolean {
|
fun isPollingActive(): Boolean {
|
||||||
|
return try {
|
||||||
val workInfos = WorkManager.getInstance(context)
|
val workInfos = WorkManager.getInstance(context)
|
||||||
.getWorkInfosForUniqueWork(HotDealPollingWorker.WORK_NAME)
|
.getWorkInfosForUniqueWork(HotDealPollingWorker.WORK_NAME)
|
||||||
.get()
|
.get()
|
||||||
|
|
||||||
return workInfos.any {
|
workInfos.any {
|
||||||
it.state == WorkInfo.State.RUNNING || it.state == WorkInfo.State.ENQUEUED
|
it.state == WorkInfo.State.RUNNING || it.state == WorkInfo.State.ENQUEUED
|
||||||
}
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user