Lesson 12: Repository pattern and WorkManager

Hanbinยท2021๋…„ 9์›” 7์ผ
0

Teach Android Development

๋ชฉ๋ก ๋ณด๊ธฐ
12/13
post-thumbnail

๐Ÿ’ก Teach Android Development

๊ตฌ๊ธ€์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ต์œก์ž๋ฃŒ๋ฅผ ์ •๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ํฌ์ŠคํŠธ์ž…๋‹ˆ๋‹ค.

Android Development Resources for Educators

Repository pattern

Existing app architecture

ViewModel์•ˆ์— ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ DAO ๊ฐ์ฒด์— ์ง์ ‘ ์ฐธ์กฐ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

์•ฑ์ด ๋„คํŠธ์›Œํฌ, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋“ฑ ์™ธ๋ถ€ ๋ฆฌ์†Œ์Šค์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ViewModel์— ์ถ”๊ฐ€ํ•ด์•ผ ํ•˜๋ฉฐ ์ถ”๊ฐ€์ ์ธ ํ™•์žฅ์— ์–ด๋ ค์›€์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ViewModel์ด ๋ณต์žกํ•ด์ง€๋ฉฐ ์ง์ ‘ ๋ฐ์ดํ„ฐ ๊ฒ€์ƒ‰์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์„ ์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

Relative data speeds

Cache network responses

์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆด ์ˆ˜ ์žˆ๋Š” ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ์œ„ํ•ด ๋กœ์ปฌ ์ €์žฅ์†Œ์— ๋„คํŠธ์›Œํฌ ์‘๋‹ต ์บ์‹ฑ์„ ๊ณ ๋ คํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๋„คํŠธ์›Œํฌ ์š”์ฒญ ์‹œ๊ฐ„์ด ๊ธด ๊ฒƒ์„ ๊ณ ๋ คํ•˜์—ฌ ์—ฌ์ „ํžˆ ์‚ฌ์šฉ์ž์—๊ฒŒ ์‘๋‹ตํ•ฉ๋‹ˆ๋‹ค.
  • ๋„คํŠธ์›Œํฌ์—์„œ ๊ฒ€์ƒ‰ํ•˜๋Š” ๋ฐ ๋น„์šฉ์ด ๋งŽ์ด ๋“ค๊ฑฐ๋‚˜ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ ๋กœ์ปฌ์—์„œ Room์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • LRU(least recently used) ๊ฐ’, FRU(frequently accessed) ๊ฐ’ ๋˜๋Š” ๊ธฐํƒ€ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์บ์‹œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Repository pattern

  • ํ˜ธ์ถœ์ž๋กœ๋ถ€ํ„ฐ ์—ฌ๋Ÿฌ data source๋ฅผ ์ถ”์ƒํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ „์†กํ•˜๋Š” ๋™์•ˆ ๋กœ์ปฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋น ๋ฅธ ๊ฒ€์ƒ‰์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฐ์ดํ„ฐ ์ƒˆ๋กœ ๊ณ ์นจ์„ ์œ„ํ•œ ๋„คํŠธ์›Œํฌ ์š”์ฒญ.(๋” ์˜ค๋ž˜ ๊ฑธ๋ฆด ์ˆ˜ ์žˆ์Œ)
  • ์•ฑ์—์„œ ๋ณ„๋„๋กœ data source๋ฅผ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

App architecture with repository pattern

Repository๋Š” data source์™€ ์•ฑ ์‚ฌ์ด์— ์ถ”์ƒํ™” ๊ณ„์ธต์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์•ฑ ์•„ํ‚คํ…์ฒ˜์—์„œ ์ด์•ผ๊ธฐํ•œ ๊ด€์‹ฌ์‚ฌ ๋ถ„๋ฆฌ ์›์น™์„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค.

Repository๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด์„œ ์ƒˆ๋กœ์šด data source๊ฐ€ ์ถ”๊ฐ€๋˜๋Š” ๊ฒฝ์šฐ ์•ฑ์˜ ํ™•์žฅ์„ฑ์ด ํ–ฅ์ƒ๋ฉ๋‹ˆ๋‹ค. Repository๋งŒ ๋ณ€๊ฒฝํ•˜๋ฉด ๋˜๊ณ  ๊ทธ ์œ„์— ๋‹ค๋ฅธ ๊ตฌ์„ฑ ์š”์†Œ(UI controller, ViewModel)๋Š” ๋Œ€๋ถ€๋ถ„ ๋™์ผํ•˜๊ฒŒ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ data soucre๋ฅผ mock ํ•˜์—ฌ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Implement a repository class

  • ๋ฐ์ดํ„ฐ ์•ก์„ธ์Šค๋ฅผ ์œ„ํ•œ ๊ณตํ†ต ์ธํ„ฐํŽ˜์ด์Šค ์ œ๊ณต.
    • ๊ธฐ๋ณธ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฒ€์ƒ‰ํ•˜๊ณ  ์ˆ˜์ •ํ•˜๊ธฐ ์œ„ํ•œ ํ•จ์ˆ˜ ๋…ธ์ถœ.
  • data source์— ๋”ฐ๋ผ Repository๋Š” ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์žˆ๋Š” ๊ฒฝ์šฐ, DAO์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.
    • ์›น ์„œ๋น„์Šค์— ์—ฐ๊ฒฐํ•˜๋Š” ๊ฒฝ์šฐ ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

WorkManager

  • Android Jetpack architecture ๊ตฌ์„ฑ์š”์†Œ.
  • ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ž‘์—…์„ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•œ ๊ถŒ์žฅ ์†”๋ฃจ์…˜.(์ฆ‰์‹œ ๋˜๋Š” ์—ฐ๊ธฐ)
  • ๊ธฐํšŒ์ฃผ์˜์ ์ด๊ณ (๊ฐ€๋Šฅํ•œ ๋น ๋ฅด๊ฒŒ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ž‘์—… ์ˆ˜ํ–‰) ๋ณด์žฅ๋œ ์‹คํ–‰.
  • ํŠน์ • ์กฐ๊ฑด์— ๋”ฐ๋ผ ์‹คํ–‰ ๊ฐ€๋Šฅ.

When to use WorkManager

Immediate tasks : ์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ๋ฅผ ์„œ๋ฒ„์— ๋™๊ธฐํ™”ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์ด ์ฆ‰์‹œ ์‹คํ–‰ํ•ด์•ผ ํ•˜๋Š” ์ž‘์—…. ์‚ฌ์šฉ์ž๊ฐ€ ์ทจ์†Œํ•  ์ˆ˜ ์žˆ๋Š” ์ž‘์—…์˜ ๊ฒฝ์šฐ Coroutines์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

Deferred tasks : ์‚ฌ์šฉ์ž ์ƒํ˜ธ ์ž‘์šฉ์— ์ง์ ‘ ์—ฐ๊ฒฐ๋˜์ง€ ์•Š๊ณ  ๋‚˜์ค‘์— ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“  ์ž‘์—…. WorkManager๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

Exact tasks : ์ž‘์—…์ด ํŠน์ • ๋ฏธ๋ž˜ ์‹œ๊ฐ„์— ์‹คํ–‰๋˜์–ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ AlarmManager๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

Declare WorkManager dependencies

implementation "androidx.work:work-runtime-ktx:$work_version"

Important classes to know

Worker : ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์Šค๋ ˆ๋“œ์—์„œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ณ  doWork() ๋ฉ”์„œ๋“œ๋ฅผ ์žฌ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.
WorkRequest : ์ž‘์—… ์š”์ฒญ.
Constraint : ์ž‘์—…์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ์กฐ๊ฑด.
WorkManager : WorkRequest๊ฐ€ ์‹คํ–‰๋˜๋„๋ก ์˜ˆ์•ฝํ•ฉ๋‹ˆ๋‹ค.

Define the work

Worker ํด๋ž˜์Šค๋ฅผ ์„œ๋ธŒํด๋ž˜์‹ฑํ•˜๊ณ  doWork()๋ฅผ ์žฌ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

class UploadWorker(appContext: Context, workerParams: WorkerParameters) :
       Worker(appContext, workerParams) {

    override fun doWork(): Result {

       // Do the work here. In this case, upload the images.
       uploadImages()

       // Indicate whether work finished successfully with the Result
       return Result.success()
   }
}

Extend CoroutineWorker instead of Worker

WorkManager๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ฝ”๋ฃจํ‹ด์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. CoroutineWorker๋ฅผ ์„œ๋ธŒํด๋ž˜์‹ฑํ•˜๊ณ  doWork()๋ฅผ ์ผ์‹œ ์ค‘๋‹จ ํ•จ์ˆ˜๋กœ ๊ตฌํ˜„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

class UploadWorker(appContext: Context, workerParams: WorkerParameters) :
       CoroutineWorker(appContext, workerParams) {

   override suspend fun doWork(): Result {

       // Do the work here (in this case, upload the images)
       uploadImages()

       // Indicate whether work finished successfully with the Result
       return Result.success()
   }
}

WorkRequests

  • ํ•œ ๋ฒˆ ๋˜๋Š” ๋ฐ˜๋ณต์ ์œผ๋กœ ์‹คํ–‰๋˜๋„๋ก ์˜ˆ์•ฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • OneTimeWorkRequest
    • PeriodicWorkRequest
  • ๊ธฐ๊ธฐ ์žฌ๋ถ€ํŒ… ์‹œ ์ง€์†๋จ.
  • ์ˆœ์ฐจ์ ์œผ๋กœ ๋˜๋Š” ๋ณ‘๋ ฌ๋กœ ์‹คํ–‰๋˜๋„๋ก ์—ฐ๊ฒฐ ๊ฐ€๋Šฅ.
  • ์‹คํ–‰๋  ์ œ์•ฝ ์กฐ๊ฑด์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Schedule a OneTimeWorkRequest

WorkRequest๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

val uploadWorkRequest: WorkRequest =
   OneTimeWorkRequestBuilder<UploadWorker>()
       .build()

WorkManager queue์— ์ž‘์—…์„ ๋”ํ•ด์ค๋‹ˆ๋‹ค.

WorkManager.getInstance(myContext)
    .enqueue(uploadWorkRequest)

Schedule a PeriodicWorkRequest

  • ๋ฐ˜๋ณต interval ์„ค์ •
  • ๊ฐ€๋ณ€ interval ์„ค์ •(optional)

Flex interval

์˜ˆ๋ฅผ ๋“ค์–ด ์ž‘์—… ์š”์ฒญ์ด ํ•˜๋ฃจ์— ํ•œ ๋ฒˆ ์‹คํ–‰๋˜๊ธฐ๋ฅผ ์›ํ•œ๋‹ค๊ณ  ํ–ˆ์„ ๋•Œ PeriodicWorkRequest๋ฅผ ์‚ฌ์šฉํ•ด ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ฒซ ๋ฒˆ์งธ๋Š” ์˜คํ›„ 11์‹œ 50๋ถ„, ๋‹ค์Œ๋‚  ์˜ค์ „ 12์‹œ 10๋ถ„์— ์ž‘์—…์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ฒฐ๊ณผ๋Š” ์ž‘์—… ์š”์ฒญ์˜ ์˜๋„๊ฐ€ ์•„๋‹ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ž‘์—… ์š”์ฒญ์ด ๋Œ€๋žต ํ•˜๋ฃจ ๊ฐ„๊ฒฉ์œผ๋กœ ์‹คํ–‰๋˜๋„๋ก ํ•˜๋ ค๋ฉด ๊ฐ€๋ณ€ ๊ฐ„๊ฒฉ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ฐ€๋ณ€ ๊ธฐ๊ฐ„์€ repeatInterval - flexInterval์—์„œ ์‹œ์ž‘ํ•˜์—ฌ ๊ฐ„๊ฒฉ์ด ๋๋‚  ๋•Œ๊นŒ์ง€์ž…๋‹ˆ๋‹ค. ํ”Œ๋ ‰์Šค์™€ ๋ฐ˜๋ณต์„ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ€์ƒ์˜ ์˜ˆ๋ฅผ ๋“ค์–ด ๋งค์ผ ๋งˆ์ง€๋ง‰ ์‹œ๊ฐ„์— ์‹คํ–‰๋˜๋„๋ก ์˜ˆ์•ฝ๋œ ์ž‘์—…์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‘ ๋ฒˆ์งธ ์˜ˆ๋Š” ํŠน์ • ๊ฐ€๋ณ€ ๊ฐ„๊ฒฉ ๋‚ด์—์„œ ์‹คํ–‰๋˜๋„๋ก ๋ฐ˜๋ณต ๊ฐ„๊ฒฉ์„ ์กฐ์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์ด ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์š”์ฒญ์ด ์•ฝ ํ•˜๋ฃจ ๊ฐ„๊ฒฉ์œผ๋กœ ์‹คํ–‰๋  ๊ฒƒ์ด๋ผ๊ณ  ํ™•์‹ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

PeriodicWorkRequest example

๊ฐ€๋ณ€ ๊ธฐ๊ฐ„์œผ๋กœ ์ฃผ๊ธฐ์  ์ž‘์—…์„ ์ •์˜ํ•˜๋ ค๋ฉด PeriodicWorkRequest๋ฅผ ์ƒ์„ฑํ•  ๋•Œ repeatInterval๊ณผ ํ•จ๊ป˜ flexInterval์„ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ํ”Œ๋ ‰์Šค ๊ธฐ๊ฐ„์€ repeatInterval - flexInterval์—์„œ ์‹œ์ž‘ํ•˜์—ฌ ๊ฐ„๊ฒฉ์ด ๋๋‚  ๋•Œ๊นŒ์ง€์ž…๋‹ˆ๋‹ค.

๋ฐ˜๋ณต ๊ฐ„๊ฒฉ์€ PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS๋ณด๋‹ค ํฌ๊ฑฐ๋‚˜ ๊ฐ™์•„์•ผ ํ•˜๊ณ  ๊ฐ€๋ณ€ ๊ฐ„๊ฒฉ์€ PeriodicWorkRequest.MIN_PERIODIC_FLEX_MILLIS๋ณด๋‹ค ํฌ๊ฑฐ๋‚˜ ๊ฐ™์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์•„๋ž˜ ์˜ˆ์‹œ๋Š” ๋งค 1์‹œ๊ฐ„์„ ๊ธฐ์ค€์œผ๋กœ ๋งˆ์ง€๋ง‰ 15๋ถ„ ๋™์•ˆ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

val repeatingRequest = PeriodicWorkRequestBuilder<RefreshDataWorker>(
        1, TimeUnit.HOURS,    // repeatInterval
        15, TimeUnit.MINUTES  // flexInterval
    ).build()

Enqueue periodic work

์ •๊ธฐ ์ž‘์—…์€ ๊ณ ์œ ํ•œ ์ด๋ฆ„์œผ๋กœ ์‹๋ณ„๋˜์–ด์•ผ ํ•˜๋ฉฐ ๊ธฐ์กด ์š”์ฒญ์— ๋™์ผํ•œ ์ด๋ฆ„์ด ์žˆ๋Š” ๊ฒฝ์šฐ ์ด ์š”์ฒญ์„ ๋ฌด์‹œํ• ์ง€ ์ด์ „ ์š”์ฒญ์„ ์ทจ์†Œํ•˜๊ณ  ๋Œ€์ฒดํ• ์ง€ ์—ฌ๋ถ€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ExistingPeriodicWorkPolicy๊ฐ€ ํฌํ•จ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

ExistingPeriodicWorkPolicy: ์ถฉ๋Œ ์‹œ ๊ณ ์œ ํ•œ PeriodicWorkRequest์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ถฉ๋Œ ํ•ด๊ฒฐ ์ •์ฑ…์„ ์—ด๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

ExistingPeriodicWorkPolicy.KEEP: ๋™์ผํ•œ ๊ณ ์œ  ์ด๋ฆ„์„ ๊ฐ€์ง„ ๊ธฐ์กด ๋ณด๋ฅ˜(์™„๋ฃŒ๋˜์ง€ ์•Š์€) ์ž‘์—…์ด ์žˆ๋Š” ๊ฒฝ์šฐ ์•„๋ฌด ์ž‘์—…๋„ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์ƒˆ๋กœ ์ง€์ •๋œ ์ž‘์—…์„ ์‚ฝ์ž…ํ•˜์‹ญ์‹œ์˜ค.

ExistingPeriodicWorkPolicy.REPLACE: ๋™์ผํ•œ ๊ณ ์œ  ์ด๋ฆ„์„ ๊ฐ€์ง„ ๊ธฐ์กด ๋ณด๋ฅ˜(๋ฏธ์™„๋ฃŒ) ์ž‘์—…์ด ์žˆ๋Š” ๊ฒฝ์šฐ ์ทจ์†Œ ๋ฐ ์‚ญ์ œ ํ›„ ์ƒˆ๋กœ ์ง€์ •๋œ ์ž‘์—…์„ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค.

WorkManager.getInstance().enqueueUniquePeriodicWork(
    "Unique Name",
    ExistingPeriodicWorkPolicy.KEEP, // or REPLACE 
    repeatingRequest
)

Work input and output

Define Worker with input and output

์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ์ž…๋ ฅ ๋ฐ์ดํ„ฐ๊ฐ€ ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž…๋ ฅ ๊ฐ’์€ ๋ฐ์ดํ„ฐ ๊ฐ์ฒด์— key-value ์Œ์œผ๋กœ ์ €์žฅ๋˜๋ฉฐ ์ž‘์—… ์š”์ฒญ ์‹œ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ž…๋ ฅ ๊ฐ’์˜ ๊ฒฝ์šฐ inputData ๊ฐ์ฒด์— ์ ‘๊ทผํ•˜์—ฌ ์ฒ˜๋ฆฌํ•˜๊ณ  ๊ฒฐ๊ณผ๋Š” Result.success(output)์„ ์‚ฌ์šฉํ•˜์—ฌ ์ž‘์—…์˜ ์ถœ๋ ฅ์œผ๋กœ ์„ค์ •๋ฉ๋‹ˆ๋‹ค.

class MathWorker(context: Context, params: WorkerParameters):
      CoroutineWorker(context, params)  {

    override suspend fun doWork(): Result {
        val x = inputData.getInt(KEY_X_ARG, 0)
        val y = inputData.getInt(KEY_Y_ARG, 0)
        val result = computeMathFunction(x, y)
        val output: Data = workDataOf(KEY_RESULT to result)
        return Result.success(output)
    }
}

Result output from doWork()

doWork()์—์„œ ๋ฐ˜ํ™˜๋˜๋Š” Result ๊ฐ์ฒด์˜ ๊ฒฝ์šฐ ์„ฑ๊ณต๊ณผ ์‹คํŒจ ์„ ํƒ์ ์œผ๋กœ ์ถœ๋ ฅ Data ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Send input data to Worker

WorkRequest๋ฅผ ํ†ตํ•ด inputData๋ฅผ Worker์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

val complexMathWork = OneTimeWorkRequest<MathWorker>()
   .setInputData(
       workDataOf(
           "X_ARG" to 42,
           "Y_ARG" to 421,
       )
   ).build()

WorkManager.getInstance(myContext).enqueue(complexMathWork)

WorkRequest constraints

Constraints

Worker๊ฐ€ ์‹คํ–‰๋˜์–ด์•ผ ํ•  ๋•Œ ์ œ์•ฝ ์กฐ๊ฑด์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Constraints.Builder๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ WorkRequest ๋‚ด์—์„œ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • setRequiredNetworkType
  • setRequiresBatteryNotLow
  • setRequiresCharging
  • setTriggerContentMaxDelay
  • requiresDeviceIdle

Constraints example

setRequiredNetworkType() : ์žฅ์น˜๊ฐ€ WorkRequest๋ฅผ ์‹คํ–‰ํ•  ํŠน์ • NetworkType์„ ๊ฐ€์ ธ์•ผ ํ•˜๋Š”์ง€๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. NetworkType.UNMETERED๋Š” ์žฅ์น˜์˜ ๋„คํŠธ์›Œํฌ ์œ ํ˜•์— ๋ฐ์ดํ„ฐ ์ƒํ•œ ๋˜๋Š” ์ œํ•œ์ด ์—†์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.(์ผ๋ฐ˜์ ์œผ๋กœ Wi-Fi๋ฅผ ์˜๋ฏธํ•จ)

setRequiresCharging() : ์ถฉ์ „์„ ์œ„ํ•ด ๊ธฐ๊ธฐ๋ฅผ ์—ฐ๊ฒฐํ•ด์•ผ ํ•˜๋Š”์ง€.

setRequiresBatteryNotLow() : ์žฅ์น˜ ๋ฐฐํ„ฐ๋ฆฌ๊ฐ€ ๋‚ฎ์•„์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค.

setRequiresDeviceIdle() : WorkRequest๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ์žฅ์น˜๊ฐ€ ์œ ํœด ์ƒํƒœ์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ •๊ธฐ์ ์ธ ์ž‘์—…์— ์ œ์•ฝ์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ ์ •์˜๋œ ๋ฐ˜๋ณต ๊ฐ„๊ฒฉ์ด ์ง€๋‚˜๋„ ์ œ์•ฝ ์กฐ๊ฑด์— ์ถฉ์กฑ๋  ๋•Œ๊นŒ์ง€ PeriodicWorkRequest๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

val constraints = Constraints.Builder()
    .setRequiredNetworkType(NetworkType.UNMETERED)
    .setRequiresCharging(true)
    .setRequiresBatteryNotLow(true)
    .setRequiresDeviceIdle(true)
    .build()

val myWorkRequest: WorkRequest = OneTimeWorkRequestBuilder<MyWork>()
    .setConstraints(constraints)
    .build()

0๊ฐœ์˜ ๋Œ“๊ธ€