Android/Coroutine

Coroutine

${Harvey} 2022. 11. 22. 17:49

 

기존에는 비동기식 프로그램을 순차적으로 해결하기위해 아래와 같이 코드를 작성해야했다.(CallBack Hell)

 

콜백지옥.

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val api = RetrofitInstance.getInstance().create(MyApi::class.java)

        // 1. 유저 정보를 가져와서 (userId)
        api.getPost1().enqueue(object : Callback<Post> {
            override fun onResponse(call: Call<Post>, response: Response<Post>) {
                Log.d("API1", response.body().toString())
                // 2. userId 기반으로 데이터를 가져오고 가져온 닉네임값
                api.getPostNumber(2).enqueue(object : Callback<Post> {
                    override fun onResponse(call: Call<Post>, response: Response<Post>) {
                        Log.d("API2", response.body().toString())
                        // 3. 닉네임 기반으로 데이터를 가져오고 유저의 댓글을 가져와서
                        api.getPostNumber(3).enqueue(object : Callback<Post> {
                            override fun onResponse(call: Call<Post>, response: Response<Post>) {
                                Log.d("API3", response.body().toString())
                                // 4. 유저의 댓글 기반으로, 대댓글
                                api.getPostNumber(4).enqueue(object : Callback<Post> {
                                    override fun onResponse(call: Call<Post>, response: Response<Post>) {
                                        Log.d("API4", response.body().toString())
                                    }

                                    override fun onFailure(call: Call<Post>, t: Throwable) {
                                        Log.d("API4", "fail")
                                    }

                                })
                            }

                            override fun onFailure(call: Call<Post>, t: Throwable) {
                                Log.d("API3", "fail")
                            }

                        })
                    }

                    override fun onFailure(call: Call<Post>, t: Throwable) {
                        Log.d("API2", "fail")
                    }

                })
            }

            override fun onFailure(call: Call<Post>, t: Throwable) {
                Log.d("API1", "fail")
            }

        })







    }
}
 
 

 

 

Coroutine

콜백 지옥에서 벗어날수 있는 Coroutine.

코루틴에 대하여 간단히 설명하자면 코루틴은 동시성 프로그래밍을 가능토록 만들어 주는 친구이다. 비 동기 작업을 효율적으로 해줄 수 있게 해준다. 코루틴도 깊게 들어가면 정말 많은 내용들이 있기에 앞에서 간단히 설명 하였다. 코루틴에 대하여 이해하는데에는 아래의 글이 많이 도움이 되었다.

https://wooooooak.github.io/kotlin/2019/08/25/코틀린-코루틴-개념-익히기/

build.gradle

implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.1")
 

 

 

MainActivity.kt

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        Log.d("TEST","START")
        CoroutineScope(Dispatchers.IO).launch{
            Log.d("TEST","CoroutineScope START")
            a()
            b()
            Log.d("TEST","CoroutineScope END")
        }

        Log.d("TEST","END")
    }

    //START ->END ->AP1 ->BP1 -> AP2 ->BP2


    suspend fun a(){   //suspend:유예하다.

        //a작업 2초정도 걸림.

        delay(1000)
        Log.d("TEST","AP1")
        delay(1000)
        Log.d("TEST","API2" )
    }
    suspend fun b(){

        //B작업 2초정도 걸림.

        delay(1000)

        Log.d("TEST","BP1")

        delay(1000)
        Log.d("TEST","BPI2" )
    }
}
 

결과: 순차대로 log가 찍힌다.

Coroutine은 일시중단 가능하다. Coroutine이 일시중단 되려면 수행되는 위치 또한 코루틴 내부여야 하기에

외부에 suspend fun(일시중단 가능 함수)로 만들어 사용하거나 로직을 Coroutine내부로 옮겨 사용해야한다.