Kotlin Room database, KTX ViewModel을 활용을 한 메모앱 만들기







개발환경


안드로이드 스튜디오 4.1.1
JDK 1.8
모든 코드는 간단한 메모앱(github)에 있습니다.


완성된 앱






프로젝트 생성

Empty Activity 선택





Language를 Kotlin으로 선택
Minimum SDK API21 선택 후 Finish 클릭


UI 그리기

ConstraintLayout에 값을 입력할 EditText 하나, 이벤트를 위한 Button 하나
입력 된 데이터를 보여주기 위한 TextView 하나를 그려줍니다.
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">


<EditText
android:id="@+id/editTextTextPersonName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:ems="10"
android:inputType="textPersonName"
app:layout_constraintEnd_toStartOf="@+id/button"
app:layout_constraintHorizontal_bias="0.497"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="메모" />

<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:text="Button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="추가" />

<TextView
android:id="@+id/textView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="16dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="24dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/editTextTextPersonName" />
</androidx.constraintlayout.widget.ConstraintLayout>

의존성 추가

  
  def room_version = "2.2.5"

implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"

// optional - Kotlin Extensions and Coroutines support for Room
implementation "androidx.room:room-ktx:$room_version"

// optional - Test helpers
testImplementation "androidx.room:room-testing:$room_version"

Room database에서 사용되는 라이브러리를 추가합니다.

도메인


  package com.barasan.myapp01
import androidx.room.Entity
import androidx.room.PrimaryKey

  @Entity
data class Memo(var title: String) {
@PrimaryKey(autoGenerate = true) var id: Int = 0
}









@Entity 어노테이션은 class명으로 테이블을 생성합니다.
@PrimaryKey는 해당 프로퍼티를 기본키로 지정되게 합니다.
데이터 insert시 자동증가 시키기 위해 autoGenerate를 true로 주었습니다.


Dao


@Dao
interface MemoDao {
@Query("SELECT * FROM Memo")
fun getAll(): LiveData<List<Memo>>

@Insert
suspend fun insert(memo: Memo)
}

@Dao으로 해당 class가 Room database에서 사용되는 Dao임을 알려줍니다.
@Query 쿼리가 실행됩니다.
  • LiveData로 감싸주면 데이터가 변경되는 시점에 UI를 업데이트 시킬수 있습니다.
@Insert 파라메터로 들어오는 Memo가 insert 됩니다.
  • insert 앞에 suspend라는 키워드가 붙었는데 비동기로 처리됨을 의미합니다.

Database


@Database(entities = [Memo::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun memoDao(): MemoDao
}

생성될 Database를 정의합니다.



ViewModel


class MemoViewModel(application: Application): AndroidViewModel(application) {
private val db = Room.databaseBuilder(
application,
AppDatabase::class.java, "memo-db"
).build()

fun getAll(): LiveData<List<Memo>> {
return db.memoDao().getAll()
}

fun insert(memo: String) {
viewModelScope.launch(Dispatchers.IO) {
db.memoDao().insert(Memo(memo))
}
}
}

Room database를 생성하고 activity에서 사용되는 조회, 등록 메소드를 정의합니다.
insert는 suspend 메소드라 launch 블럭 안에서 실행 시킵니다.


MainActivity


class MainActivity : AppCompatActivity() {

val viewModel: MemoViewModel by viewModels()

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

button.setOnClickListener {
viewModel.insert(editTextTextPersonName.text.toString())
}

viewModel.getAll().observe(this, {
textView.text = it.toString()
})
}
}

MemoViewModel를 가져올때 by viewModels()로 가져옵니다.
KTX viewmodel를 활용한 방법입니다.
viewModel.getAll().observe()
  • 데이터가 insert 될때 실행되기 때문에 항상 최신의 데이터를 보여줄 때 좋습니다.
  • LiveData로 감싸 주어야 observe 메소드를 사용할 수 있습니다.

findByView를 사용하지 않고 바로 view에 접근하기 위해서는 plugin에
id 'kotlin-android-extensions'를 추가해 주어야 합니다.



















댓글