Android

Android Coroutine - 소개와 사용

이성진씨 2021. 4. 11. 17:36

01. Coroutine 소개와 설정

Android에서 비동기 코드를 실행할 수 있게 해주는 기능으로 네트워크, Database접근 등에 주로 사용됩니다.

Coroutine을 사용하기 위해서는 CoroutineScope를 이용해야합니다. 코루틴 작업단위를 지정해주며 해당 CoroutineScope에 Dispatcher의 종류를 지정해주어 현재 작업량이 어떤 thread에서 실행될지 알려줄 수 있습니다.

 

 - 장점

- 경량

Thread로 작업을 실행하는 경우 스레드를 생성, 해제 하면서 Thread의 상태를 저장하고 다시 불러오는 비용(Context Switching)이 들지만 Coroutine의 경우 작업을 일시중단하는 방식이라 Context Switching에 비용이 들지 않습니다.

 

- 구조에 맞는 Scope 제공

Coroutine에서 Dispatcher를 통해서 구조에 맞는 작업을 사용자 임의대로 번갈아가며 호출할 수 있습니다.

 

코루틴 사용방법을 살펴보겠습니다.

plugins {
    ...
}

android {
    ...
}

dependencies {

    ...
    //Coroutine 01 - 01
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1"
}

가장 먼저 build.gradle(Module)에 coroutine depencency와 database사용을 위한 RoomDatabase depencency를 추가해주도록 합니다. RoomDatabase사용에 대한 설정은 RoomDatabase 포스트 sungjinlee.tistory.com/7에서 확인할 수 있습니다.

 

02. Coroutine 간단한 사용

위의 글에서 Coroutine에 대한 dependency가 추가되었습니다. 이제 CoroutineScope를 통해 Activity내에서 사용해보겠습니다.

class MainActivity : AppCompatActivity() {

    lateinit var textView: TextView
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        textView = findViewById(R.id.text)

        CoroutineScope(Dispatchers.Main).launch {
            //Android 기본 thread에서 실행 (UI와 상호작용)
        }
        CoroutineScope(Dispatchers.Default).launch {
            //기본 thread외부에서 실행 (CPU를 많이 사용하는 작업으로 목록정렬, json파싱)
        }
        CoroutineScope(Dispatchers.IO).launch {
            //기본 thread외부에서 실행 (Database, Network작업)
            val apiText = getApiTextAfterTwoSec()
            withContext(Dispatchers.Main) {
                textView.text = apiText
            }
        }
        CoroutineScope(Dispatchers.Unconfined).launch {
            //위의 작업들과는 조금 다른 형태로 상태가 중지되었다가 다시 시작하게되면 적절한 thread에
            // 재할당되는 형식이라 특정스레드로 지정되어야하는 경우 사용하면 안됨
        }
    }

    suspend fun getApiTextAfterTwoSec(): String {
        delay(2000)
        return "api Text"
    }
}

기본적인 Dispatcher활용하여 함수를 호출하고 해당 return값을 표시해주는 코드입니다.

 

가장먼저 suspend fun 함수를 만들어줘야 하는데 suspend 함수는 coroutine내에서 호출하기 위한 함수로 CoroutineScope내에서 호출하고 2초후에 String을 반환해주는 역할을 하고 있습니다.

2초를 멈추도록 하는 delay함수가 있는데 이는 thread.sleep과 같이 현재 thread의 다른 작업들을 모두 멈추는 것이 아니라 하나의 Coroutine만 2초동안 멈추도록 하는 것입니다. 만약 해당 Thread안에 여러개의 coroutineScope 가 있었다면 Thread.sleep을 호출하는 순간 다른 코루틴들 또한 멈추게 되었을 것입니다.

그리고 각 Dispatcher별로 CoroutineScope를 생성해놓았는데 크게 Main, Default, IO, Unconfined로 구분되어 있습니다. 해당 작업이 어떤 Thread에서 일어날 지 지정하는 것으로 사용하기 적절한 작업내용은 주석으로 정리해놓았습니다.

 

그럼 이제 getApiTextAfterTwoSec함수를 호출하고 있는 Dispatchers.IO에서 호출하고 2초후에 "api_text"라는 문자열을 apiText 객체에 넣어주었습니다. 그리고 textView의 글을 바꿔주기 위해 withContext(Dispatchers.Main)을 호출하고 있는데 Android에서는 MainThread가 아닌 다른 Thread에서 UI를 참조할 경우 crash가 나게 됩니다. 그렇기 때문에 withContext라는 Coroutine함수로 해당 작업은 MainThread로 이동하여 처리되도록 표시해두었습니다.

 

이 외에 다른 예약어들은 추가적인 포스트 작성을 통해 설명하겠습니다.

 

포스트된 내용에 대해 미흡한 점이나 궁금증이 있으시다면 댓글로 알려주시면 답변드리겠습니다. 😀

 

참조할 수 있는 코드는 github에서 확인할 수 있습니다.

github.com/adwx13/CoroutineStudy.git

 

참조

developer.android.com/kotlin/coroutines?hl=ko

myungpyo.medium.com/%EC%BD%94%EB%A3%A8%ED%8B%B4-%EA%B3%B5%EC%8B%9D-%EA%B0%80%EC%9D%B4%EB%93%9C-%EC%9E%90%EC%84%B8%ED%9E%88-%EC%9D%BD%EA%B8%B0-part-1-dive-2-25b21741763a

blog.yena.io/studynote/2020/04/26/Android-Kotlin-Coroutine.html

medium.com/@limgyumin/%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-%EB%A5%BC-%EC%9C%84%ED%95%9C-%EC%BD%94%ED%8B%80%EB%A6%B0-%EC%BD%94%EB%A3%A8%ED%8B%B4-81eab8b9fd21

thdev.tech/kotlin/2018/10/04/Kotlin-Coroutines/

labs.brandi.co.kr/2020/12/09/jangsc.html