Seize the day

POST : Android Dev Study

WorkManager 실습

매일마다 새벽 0시 부터 6시 사이의 랜덤한 시간에 sync()를 호출하는 기능을 WorkManager를 이용해서 구현하기. SyncWorker에는 파라미터가 없어서 최대한 간단히 

WorkManager를 사용한 백그라운드 작업 - Kotlin  |  Android 개발자  |  Android Developers 
WorkManager periodicity. A deep dive into how WorkManager handle… | by Pietro Maggi | Android Developers | Medium 참고

 

build.gradle

implementation "androidx.work:work-runtime-ktx:2.3.4"

Settings.kt

val isAutoSync = SettingBoolean("isAutoSync", false)
val nextSyncTime = SettingLong("nextSyncTime", 0L)
val lastSyncTime = SettingLong("lastSyncTime", 0L)

SyncWorker.kt

class SyncWorker(private val context: Context, params: WorkerParameters) : Worker(context, params) {

    override fun doWork(): Result {
        if (Settings.isAutoSync.value) {
            try {
                SyncManager().sync(true)

                Settings.lastSyncTime.value = System.currentTimeMillis()
            } catch (_: Exception) {
                Settings.lastSyncTime.value = -1L
                DUtils.notReached()
            }

            SyncWorkerManager.enqueueWorker(context)
        } else {
            Settings.nextSyncTime.value = 0L
        }
        return Result.success()
    }
}


object SyncWorkerManager {

    private const val UNIQUE_WORK_NAME = "SYNC_WORKER"

    fun enqueueWorker(context: Context) {
        val currentDate = Calendar.getInstance()
        val dueDate = Calendar.getInstance()
        val random = SecureRandom()
        dueDate.add(Calendar.DATE, 1) // tomorrow
        dueDate.set(Calendar.HOUR_OF_DAY, random.nextInt(7)) // 0 ~ 6
        dueDate.set(Calendar.MINUTE, random.nextInt(60)) // 0 ~ 59
        dueDate.set(Calendar.SECOND, random.nextInt(60)) // 0 ~ 59
        if (dueDate.before(currentDate)) {
            dueDate.add(Calendar.HOUR_OF_DAY, 24)
        }
        val timeDiff = dueDate.timeInMillis - currentDate.timeInMillis

        val constraints = Constraints.Builder()
            .setRequiredNetworkType(NetworkType.CONNECTED)
            .build()

        val dailyWorkRequest = OneTimeWorkRequestBuilder<SyncWorker>()
            .setConstraints(constraints)
            .setInitialDelay(timeDiff, TimeUnit.MILLISECONDS)
            .build()

        WorkManager
            .getInstance(context)
            .beginUniqueWork(
                UNIQUE_WORK_NAME,
                ExistingWorkPolicy.REPLACE,
                dailyWorkRequest
            )
            .enqueue()

        Settings.nextSyncTime.value = dueDate.timeInMillis
    }

    fun cancelWork(context: Context) {
        WorkManager.getInstance(context).cancelUniqueWork(UNIQUE_WORK_NAME)
        Settings.nextSyncTime.value = 0L
    }
}

SettingsMainActivity.kt

private void toggleAutoSyncView() {
        boolean isChecked = !autoSyncView.isChecked();
        Settings.INSTANCE.isAutoSync().setValue(isChecked);
        if (isChecked) {
            SyncWorkerManager.INSTANCE.enqueueWorker(this);
        } else {
            SyncWorkerManager.INSTANCE.cancelWork(this);
        }
        updateAutoSyncView(isChecked);
    }

    private void updateAutoSyncView(boolean isAutoSync) {
        autoSyncView.setChecked(isAutoSync);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM/dd HH:mm");
        StringBuilder sb = new StringBuilder();
        sb.append("last: ");
        long lastSyncTime = Settings.INSTANCE.getLastSyncTime().getValue();
        if (lastSyncTime == 0L) {
            sb.append("None");
        } else if (lastSyncTime < 0L) {
            sb.append("Error");
        } else {
            sb.append(simpleDateFormat.format(new Date(lastSyncTime)));
        }
        if (isAutoSync) {
            sb.append(", next: ");
            long nextSyncTime = Settings.INSTANCE.getNextSyncTime().getValue();
            if (nextSyncTime <= 0L) {
                sb.append("None");
            } else {
                sb.append(simpleDateFormat.format(new Date(nextSyncTime)));
            }
        }
        autoSyncView.getDescriptionView().setVisibility(View.VISIBLE);
        autoSyncView.getDescriptionView().setText(sb.toString());
    }

 

대충 돌아는 가는 듯..

top

posted at

2021. 10. 3. 00:14


CONTENTS

Seize the day
BLOG main image
김대정의 앱 개발 노트와 사는 이야기
RSS 2.0Tattertools
공지
아카이브
최근 글 최근 댓글
카테고리 태그 구름사이트 링크