본문 바로가기

안드로이드/JetPack

[안드로이드] 4. Room 비동기처리 (feat. Coroutine)

지난번 문서까지의 리뷰

Room을 이용하여 할일 목록을 화면 상에 업데이트 중이었고, LiveData를 통해 테이블을 관찰하여 자동으로 화면이 갱신되었다. 그리고 2. Room에서 메인쓰레드에서 쿼리를 가능하게 했음을 기억할 것이다. 이는 임시방편이었고 사실상 DB 작업은 메인 쓰레드에서 쿼리를 허용하는 것은 앱의 성능을 저하한다.

 

val db = Room.databaseBuilder(  applicationContext,AppDatabase::class.java, "database-name"
        ).allowMainThreadQueries() //문제가 되는 부분
         .build()

 

백그라운드에서 DB 작업을 하기 위한 방식

  1. 쓰레드를 사용한다. - Java & Kotlin
  2. AsyncTask를 사용한다. - Java
  3. Coroutine을 사용한다. - Kotlin

우리는 현재 코틀린을 이용하기 때문에 Coroutine을 활용한 백그라운드 처리를 할 것이다. Coroutine이란, 자바에서 제공되지 않는 쓰레딩 방식이다.

 

Coroutin 사용 방법

먼저 build.gradle(:app)에 다음을 추가한다.

dependencies{
	...
    implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.2.0-alpha01'
    ...
 }
class MainActivity : AppCompatActivity() {

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

        val db = Room.databaseBuilder(
            applicationContext,
            AppDatabase::class.java, "database-name"
        ).build()

        db.todoDao().getAll().observe(this, Observer { todos ->
            result_textView.text = todos.toString()
        }) //getAll을 할 경우 todos로 값이 들어온다.

        add_button.setOnClickListener {
        	//Coroutine을 사용하여 해당 구문 내부 작업은 백그라운드에서 실행된다.
            lifecycleScope.launch(Dispatchers.IO) {
                db.todoDao().insert(Todo(todo_edit.text.toString()))
            }
        }
    }
}

 

안드로이드에는 두 가지 쓰레드가 존재한다.

  1. 메인 쓰레드 (혹은 UI 쓰레드)
  2. 작업 쓰레드 (Worker 쓰레드)

UI 작업은 메인 쓰레드에서만 가능하고 작업쓰레드에서는 불가능하다. 하지만, 이외의 다른 작업들은 메인, 작업 쓰레드 어디서든 가능하다. 코루틴을 보면 작업쓰레드에서의 작업을 위해 Dispatchers.IO를 추가해 준 모습이다. (일반적으로 외부 통신 및 DB 작업은 작업 쓰레드에서 비동기적으로 실행하는게 가장 효율적인 구현 방식이다.)