Android/WorkManager
${Harvey}
2022. 11. 21. 22:30
2022. 11. 21. 22:30
- WorkManager를 일정 주기마다 실행할 수 있도록 해주기.
build.gradle
implementation("androidx.work:work-runtime-ktx:2.7.1")
MainActivity.kt
//PeriodWorkRequestBuilder 들어가보면 최소 시간이 15분이라 그 이하로 설정해도 15분으로 설정된다.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val workManager = PeriodicWorkRequestBuilder<WorkManager1>(15,TimeUnit.MINUTES).build()
WorkManager.getInstance(this).enqueue(workManager) //PeriodWorkRequestBuilder 들어가보면 최소 시간이 15분이라 그 이하로 설정해도 15분으로 설정된다.
}
}
class WorkManager1(context: Context, workerParameters: WorkerParameters) : Worker(context,workerParameters){
override fun doWork(): Result {
Log.d("WorkerManager1","doWork")
val format = SimpleDateFormat("hh:mm:ss")
val currentTime = format.format(Date())
Log.d("WorkManager1",currentTime)
return Result.success()
}
}
${Harvey}
2022. 11. 21. 22:29
2022. 11. 21. 22:29
- WorkManager의 작업 진행에 따라 처리를 해줄수 있는 코드.(작업 진행률을 %로 나타내는 코드를 먼저 작성했다.)
build.gradle
implementation("androidx.work:work-runtime-ktx:2.7.1")
// WorkManager -> 진행상태 검토
// WorkManager -> 오래걸리는 작업 ( 60초 6 12 18 24 30) -> 몇 퍼센트 진행이 되었다.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val workManagerTest = OneTimeWorkRequestBuilder<WorkManagerTest>().build()
WorkManager.getInstance(this).enqueue(workManagerTest)
WorkManager.getInstance(this)
.getWorkInfoByIdLiveData(workManagerTest.id)
.observe(this, Observer { workInfo : WorkInfo? ->
val progress = workInfo?.progress
val value = progress?.getInt(HowMuch,0)
if(value != 0){
Log.d("MainActivity",value.toString()+"%")
}
if(value == 100){
Log.d("MainActivity","이제 끝끝")
}
})
}
}
class WorkManagerTest(context : Context, params : WorkerParameters) : CoroutineWorker(context, params) {
companion object{
const val HowMuch = "progress"
}
override suspend fun doWork(): Result {
// i -> 1,2,3,4,5,6,7,8,9,10 / 10 20 30 40
for(i in 1..10){
val result = workDataOf(HowMuch to i*10)
setProgress(result)
delay(1000)
}
return Result.success()
}
}
${Harvey}
2022. 11. 21. 22:27
2022. 11. 21. 22:27
implementation("androidx.work:work-runtime-ktx:2.7.1")
// WorkManager + Coroutine
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val workManager = OneTimeWorkRequestBuilder<WorkManager2>().build()
WorkManager.getInstance(this).enqueue(workManager)
}
}
class WorkManager1(context : Context, workerParameters: WorkerParameters) : Worker(context, workerParameters){
override fun doWork(): Result {
return Result.success()
}
}
class WorkManager2(context : Context, params : WorkerParameters) : CoroutineWorker(context, params){
override suspend fun doWork(): Result {
withContext(Dispatchers.IO){
test1()
test2()
}
return Result.success()
}
suspend fun test1() {
for(i in 1..3) {
delay(1000)
Log.d("WorkManager2 test1", i.toString())
}
}
suspend fun test2() {
for(i in 1..3) {
delay(1000)
Log.d("WorkManager2 test2", i.toString())
}
}
}
결과: Coroutine을 사용하여 test1(),test2()가 순차적(비동기식) 으로 코드가 실행된다.
${Harvey}
2022. 11. 21. 22:25
2022. 11. 21. 22:25
- A와B는 무엇이 먼저 실행되던 상관이 없으나 C는 무조건 A/B 모두 실행되고 실행되어야 하는, 이러한 상황에 사용하는 코드
build.gradle
implementation("androidx.work:work-runtime-ktx:2.7.1")
// WorkManager Chaining
// A -> 순서 상관 없이 실행되도 괜찮음
// B -> 순서 상관 없이 실행되도 괜찮음
// C -> 무조건 A / B 모두 실행 된 뒤에 실행되어야 한다
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val workManagerA = OneTimeWorkRequestBuilder<WorkManagerA>().build()
val workManagerB = OneTimeWorkRequestBuilder<WorkManagerB>().build()
val workManagerC = OneTimeWorkRequestBuilder<WorkManagerC>().build()
// WorkManager.getInstance(this).enqueue(workManagerA)
// WorkManager.getInstance(this).enqueue(workManagerB)
// WorkManager.getInstance(this).enqueue(workManagerC)
WorkManager.getInstance(this)
.beginWith(listOf(workManagerA, workManagerB))
.then(workManagerC)
.enqueue()
}
}
class WorkManagerA(context : Context, workerParameters: WorkerParameters) : Worker(context, workerParameters){
override fun doWork(): Result {
for(i in 0..3) {
sleep(1000)
Log.d("WorkManagerA", i.toString())
}
return Result.success()
}
}
class WorkManagerB(context : Context, workerParameters: WorkerParameters) : Worker(context, workerParameters){
override fun doWork(): Result {
for(i in 0..3) {
Thread.sleep(1000)
Log.d("WorkManagerB", i.toString())
}
return Result.success()
}
}
class WorkManagerC (context : Context, workerParameters: WorkerParameters) : Worker(context, workerParameters){
override fun doWork(): Result {
for(i in 0..3) {
Thread.sleep(1000)
Log.d("WorkManagerC", i.toString())
}
return Result.success()
}
}
${Harvey}
2022. 11. 21. 22:24
2022. 11. 21. 22:24
implementation("androidx.work:work-runtime-ktx:2.7.1")
// WorkManager 데이터 주고 받는거
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// val workManagerA = OneTimeWorkRequestBuilder<WorManagerA>().build()
// WorkManager.getInstance(this).enqueue(workManagerA)
val myData : Data = workDataOf(
"a" to 10,
"b" to 20
)
val workManagerB = OneTimeWorkRequestBuilder<WorkManagerB>().setInputData(myData).build()
WorkManager.getInstance(this).enqueue(workManagerB)
WorkManager.getInstance(this).getWorkInfoByIdLiveData(workManagerB.id)
.observe(this, Observer { info ->
if(info != null && info.state.isFinished) {
val result = info.outputData.getInt("result", 10000)
val result2 = info.outputData.getInt("result2", 10000)
Log.d("MainActivity", result.toString())
Log.d("MainActivity", result2.toString())
}
})
}
}
class WorManagerA(context : Context, workerParameters: WorkerParameters) :
Worker(context, workerParameters){
override fun doWork(): Result {
for(i in 1..10) {
sleep(1000)
Log.d("WorManagerA", i.toString())
}
return Result.success()
}
}
class WorkManagerB(context : Context, workerParameters: WorkerParameters) :
Worker(context, workerParameters){
override fun doWork(): Result {
val a = inputData.getInt("a", 1000)
val b = inputData.getInt("b", 2000)
val c = inputData.getInt("c", 3000)
Log.d("WorkManagerB", a.toString())
Log.d("WorkManagerB", b.toString())
Log.d("WorkManagerB", c.toString())
val output : Data = workDataOf("result" to 10)
return Result.success(output)
}
}
실행결과: WorkManagerB의 값 10을 전달한다. result2는 존재하지 않아 default값인 1000을 출력한다.
${Harvey}
2022. 11. 21. 22:06
2022. 11. 21. 22:06
- WorkManager
- WorkManager는 안드로이드 백그라운드 작업을 처리하는 방법 중 하나이며 Android Jetpack 아키텍처 구성 요소중 하나이다.
- 앱이 종료되거나 기기가 다시 시작되어도 실행 예정인, 지연 가능한 비동기 작업을 쉽게 예약할 수 있도록 해준다.
- 주로 사용자가 나가거나 하더라도 오래걸리는 작업(Calendar 동기화, 이미지 프로세싱)등에 쓰인다.
build.gradle
//WorkManager
implementation("androidx.work:work-runtime-ktx:2.7.1")
// https://developer.android.com/topic/libraries/architecture/workmanager
// https://developer.android.com/codelabs/android-workmanager#0
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
SimpleThread().start()
val workManagerA = OneTimeWorkRequestBuilder<WorkManagerA>().build()
WorkManager.getInstance(this).enqueue(workManagerA)
}
}
class SimpleThread : Thread() {
override fun run() {
super.run()
for(i in 1..10){
Log.d("MainActivity","$i")
sleep(1000)
}
}
}
class WorkManagerA(context : Context, workerParameters : WorkerParameters) : Worker(context,workerParameters) {
override fun doWork(): Result {
for(i in 1..10){
sleep(1000)
Log.d("WorkManagerA",i.toString())
}
return Result.success()
}
}
앱 종료시 WorkManager의 로그만 찍힌다.