[Android] 코루틴 왜 써야하는가

    코루틴은 구글 블로그에서도 공식으로 추천하고 있는 코틀린의 기능입니다.

    블로그에 의하면 코루틴은 실시간 처리를 훨씬 쉽게 작성하고 이해할 수 있게 해준다고 합니다.

    또한 Jetpack 라이브러리 (Lifecycle ,WorkManager, Room) 에도 코루틴을 지원하여 더 나은 코드를 작성할 수 있다고 합니다.

     

     

     

    [Coroutine]

     

    - 코루틴은 루틴의 일종

    - 협동 루틴이라 할 수 있다

    - 코루틴의 "Co"는 with 또는 together을 뜻한다

     

     

     

     

    1 .코루틴은 이전에 자신의 실행이 마지막으로 중단되었던 지점 다음의 장소에서 실행을 재개한다.

     

    - 일반적으로 사용하는 함수나 루틴은 중단되는 개념이 없고 실행이되면 빠져나오고 끝인 반면에

    코루틴은 실행이 되고나서 중단과 재개를 컨트롤 할수 있다 (함수의 진입점과 출구점이 여러개다 라고도 함)

     

     

     

     

    2. 코루틴은 협력작업, 예외, 이벤트루프, 반복자, 무한목록 및 파이프 와 같은 친숙한 프로그램 구성 요소를 구현하는데 적합합니다. (..??)

     

    - 다들 비슷한 느낌을 받으실것 같습니다.

    괜찮습니다! 구글에서 코루틴이 어디에 쓰일지에 대한 가이드를 제시해 줬습니다. 

    구글에서는 비동기처리에 대해서 코루틴을 사용하는것을 추천하고 있습니다!

     

     

     

     

    3. 비동기 처리에 대한 코드를 간단한게 작성할 수 있다

     

    - 메인쓰레드가 블록킹 되는 부분에 대해서 도움을 줄 수 있다.

    - 비동기 (콜백지옥) 처리로 되어있는 코드들을 (suspend function을 이용하여) 순차적인 코드로 만들 수 있게 해준다.

     

     

     

     

     

     

    [Without Coroutine]

    
      //서버에서 받은 데이터를 넣어주는 코드
    
      val user = fetchUserData() // NetworkOnMainThreadException ❗❗
      textView.text = user.name
      

    Main Thread에서 Network Call을 하기때문에 Exception이 발생했습니다.

    이러한 문제를 해결하기 위해 thread 처리를 해줍니다.

     

     

    
      //위의 Exception을 해결하기 위해서 thread 처리를 해줌
    
      thread {
    	  val user = fetchUserData()
       	  textView.text = user.name // CalledFromWrongThreadException ❗❗
      }
      

    그러나 여기서 또 Exception이 발생합니다.

    UI Thread에서 업데이트를 해야 하는데 그렇지 않기 때문에 Exception이 발생했습니다.

     

     

    
      //함수를 만들어서 서버를 thread를 이용해서 call 하고 main thread로 전환해서 ui를 set해줌
    
      feachUserData { user -> // callback
      	textView.text = user.name
      }
      

    이렇게 해결이 가능하나 계속 중첩되면 콜백 지옥이 일어날 수 있습니다.
    또 한, cancel과 dispose를 일일이 해줘야 하고 OutOfMemory 의 우려가 있습니다.

     

     

     

     

    이런것을 해결하기 위해 구글이 코틀린의 코루틴을 적극적으로 추천했습니다.

    코루틴은 async를 간단하게 해주고 callback 을 간단하게 바꿔줄수 있습니다.

     

    [With Coroutine]

    
      fun loadUser() {
      	val user = api.feachUser()
        show(user)
      }
      
      // 위에서와 같은 문제 발생
      // Main Thread에서 서버 api를 호출하게되면 ui가 blocking 되면서 화면을 그릴수 없게됨 ❗❗
      

    이것을 해결하기 위해

     

      //새로 api를 만들어서 thread를 스위치해서 다시 ui를 업데이트 하는 콜백방식으로 해결
      
      fun loadUser() {
      	api.fetchUser { user ->
        	show(user)
      }
      

    이렇게 만들어서 해결했으나 결국 두가지다 처음 Without Coroutine에서와 같이 문제점이 생길 수 있습니다

     

     

    드디어 바로 코틀린의 코루틴을 이용하여 이런 문제점들을 해결할 수 있습니다!

    
      suspend fun loadUser() {
      	val user = api.fetchUser()
        show(user)
      }
      

    이렇게 하게 되면 신기하게도 콜백도 없고 별도의 thread 처리도 없었지만 실제 실행은 새로운 thread가 생성이 되고, network가 완료되고나서 다시 ui update까지 처리를 하게 됩니다.

     

    suspend을 붙여줌으로써 별도의 thread 생성 작업을 해주지 않아도 코틀린의 코루틴을 이용하여 이렇게 간단하게 처리를 할 수 있습니다!

     

    (코루틴을 공부중입니다. 혹시라도 틀린부분이나 보충해야할 부분이 있다면 말씀해주시면 감사하겠습니다!)

     

     

     

     

     

     

     

     

     

     

     

    references :

     

    kotlinlang.org/docs/reference/coroutines/coroutines-guide.html

     

    www.youtube.com/channel/UCJeARDV434voq3IxRTBfzL

     

    android-developers.googleblog.com/search?updated-max=2020-06-22T08:03:00-07:00&max-results=7&start=48&by-date=false

     

     

     

    댓글