티스토리 뷰

728x90

 2022.05.07 - [분류 전체보기] - 도로명 주소 개발센터 API 사용해 보기 2:DI + Hilt 사용해 보기

 

도로명 주소 개발센터 API 사용해 보기 2:DI + Hilt 사용해 보기

2022.04.28 - [안드로이드] - 도로명 주소 개발센터 API 사용해보기1 : Api활용 신청, Retrofit 도로명 주소 개발센터 API 사용해보기1 : Api활용 신청, Retrofit 앱을 개발을 하다 보면 주소를 받아야 하는 경

alanboyce.tistory.com

 

이번 포스팅의 메인 기능은 Coroutine입니다.

사실 Coroutine만 해도 양이 꽤 많이 나와서 이번 포스팅에서는 간략한 지식 + 본 예제에서 사용하는 정도의 지식만 다루고 추후에 좀 더 자세한 내용은 다른 포스팅에서 다루려고 합니다.

1. 코루틴 빌더

코루틴의 기능을 이용하기 위해 코루틴을 생성 해야합니다. 
가장 기본적인 방법은 runBlocking을 사용하는 방법입니다.

fun main() = runBlocking {

    println("Hello")
    delay(1000L)
    println("World!")

}

위와 같은 방식으로 코루틴 사용이 가능합니다

여기서 rurnBlocking과 같이 코루틴을 생성하는 역활을 하는 함수를 코루틴 빌더라고 합니다.

delay() 함수는 코루틴 함수로 인자로 받은 밀리세컨드의 시간만큼 쉬고 다음 동작을 진행하게 됩니다.

출력 결과는 Hello 출력 후 1초 뒤에 World! 가 출력됩니다.

fun main() = runBlocking {

    launch {
        println("World!")
    }

    println("Hello")

}

launch 역시 코루틴 빌더입니다.

runBlocking과 launch의 차이점은
runBlocking은 코루틴 내부의 코드들의 동작이 끝날 때까지 다른 코드 진행을 못하게 합니다
launch는 가능하면 다른 코드와 같이 동작을 진행합니다.

위의 예제에서 코드 순서로 보면 World! Hello 순으로 출력될 것 같지만 코드를 실행시키면 Hello World 순으로 출력됩니다.

이유는 launch와 runBlocking 둘 다 메인 스레드를 사용하기에 먼저 사용하고 있는 runBlocking에게 양보하게 됩니다.
그래서 Hello가 먼저 출력된 후 World! 가 출력됩니다.

runBlocking은 Hello를 먼저 출력했지만 코드 안에 있는 자식 코루틴인 launch가 진행이 완료할 때까지 기다립니다.

fun main() = runBlocking {

    runBlocking {
        println("World!")
    }

    println("Hello")

}

둘 다 runBlocking으로 하면 World! Hello가 출력되게 됩니다.

 

2. Delay()

fun main() = runBlocking {

    launch {
        println("World!")
    }

    delay(1000L)
    println("Hello")

}

위의 launch 예제에서 중간에 delay() 함수가 추가되었습니다.

Delay() 함수는 launch의 특징과 비슷하게 중단 상태일 때 다른 코루틴에게 자원을 양보합니다.
즉, 위의 코드를 순서대로 살펴보면
1. runBlocking에 의해 코루틴이 생성
2. launch는 양보를 하여 delay(1000L) 코드를 진행
3. delay()가 다시 양보를 하여 아래 코드 안 println("Helo")가 아닌 launch에게 자원이 돌아갑니다.
4. launch 코드 블록 진행 후 println("hello") 진행
결과 : World! \n Hello

이렇게 코드가 잠시 중단되는 것을 suspension point라고 합니다

참고로 코루틴 함수를 사용하면 다음과 같은 아이콘이 나오게 됩니다.

 

3. suspend 키워드

코루틴 기능을 사용하는 함수의 경우 일반적인 함수를 이용하면 에러가 발생하게 됩니다.

fun main() = runBlocking {

    launch {
        doWold()
    }

    println("Hello")

}

suspend fun doWold(){
    delay(1000L)
    println("World!")
}

위의 예에서 doWold()에 suspend 키워드를 붙이지 않으면 delay() 함수는 이용이 불가능합니다.

또한 suspend로 정의된 함수 역시 코루틴 안에서 호출되지 않으면 오류가 발생하게 됩니다.

fun main() = runBlocking {

    launch {
        doWold2()
    }

    println("Hello")

}

fun doWold2() = runBlocking {
    delay(1000L)
    println("World!")
}

suspend를 이용하지 않으려면 위와 같이 하면 되긴 하는데 특정한 이유가 있지 않으면 suspend를 이용하는 것이 좋을 것 같습니다.

 

이렇게 일단은 간단하게 코루틴에 대해 알아봤는데요

아직 많이 남아있습니다만, 처음에 언급했듯이 이번에는 완전 기본만 알아본 것이고 메인 코드로 돌아가서 사용법 위주로 진행한 뒤

추후 포스팅에서 좀 더 다루도록 하겠습니다.

 

 

4. 메인 코드

2022.04.28 - [안드로이드/코드] - 도로명 주소 개발센터 API 사용해보기1 : Api활용 신청, Retrofit

 

도로명 주소 개발센터 API 사용해보기1 : Api활용 신청, Retrofit

앱을 개발을 하다 보면 주소를 받아야 하는 경우가 종종 있습니다. 저 같은 경우 웹뷰를 이용한 다음 우편 번호 서비스를 이용해왔습니다. 이 방식을 이용하면 개발자 입장에서는 진짜 편하게

alanboyce.tistory.com

1편에서 만든 AddressService에서

interface AddressService {

    @GET("addrlink/addrLinkApi.do")
    suspend fun getAddress(
        @Query("confmKey") confmKey : String? = BuildConfig.ADDRESS_API_KEY,
        @Query("currentPage") currentPage : Int? = 1,
        @Query("countPerPage") countPerPage : Int? = 10,
        @Query("keyword") keyword : String,
        @Query("resultType") resultType : String? = "json",
        @Query("firstSort") firstSort : String? = "road"
    ): Response<AddressResult>

}

getAddress함수를 위에서 학습한 susspend로 만들어줍니다.
그리고 리턴 값을 Call 대신 Response로 바꿔줍니다.

그다음 Activity에서 다음과 같이 출력해줍니다.

runBlocking {
    try {
        val response = RetrofitUtil.service.getAddress(keyword = "서울시 강남구")
        if (response.isSuccessful) {
            response.body()?.results?.address?.forEach { address ->
                Log.e("Coroutine", "${address.roadAddr}")
            }
        }
    } catch (e: Exception) {
        e.printStackTrace()
    }
}

1편을 보셨다면 아시겠지만 코드가 많이 간결해졌음을 알 수 있습니다.

사실 네트워크 통신에서 기본적으로 사용하는 건 이걸로 끝입니다!
생각보다 간단하죠?
조금 더 응용을 하자면 Flow도 있지만 이거 역시 추후 포스팅에서 등장할 예정입니다.

 

다음 글에서는 mvvm 정확히는 AAC(Android Architecture Components)에 대해 알아보겠습니다.

728x90
댓글