Room for Local Storage in Android Apps

Dimas Rangga
Nov 4 · 4 min read

Room adalah persistance library yang mempermudah kita untuk melakukan transaksi data dengan SQLite dan mengurangi jumlah boilerplate code.

Pada artikel ini akan dijelaskan bagaimana membuat sebuah aplikasi sederhada yang mengimplementasikan room, dan menggunakan arch component.

Dari gambar diagram diatas terbagi menjadi 4 bagian

  1. RoomDatabase: layer ini difungsikan untuk memanajemen transaksi local data dengan SQLite
  2. Repository: berfungsi untuk memanajemen semua transaksi query yang akan ditampilkan ke UI melalui viewmodel
  3. ViewModel: adalah layer yang digunakan untuk menghandle semua business logic dan menyediakan data dari Model untuk UI
  4. UI Controller: adalah view yang akan di tampilkan ke user. View dapat berupa activity atau fragment.

Nah dari beberapa penjelasan diatas akan di implementasikan di aplikasi sederhana berikut :

Step 1: Update gradle depedencies

Tambahkan library room, rxjava, dan android arch component pada build.gradle kemudian sync gradle

apply plugin: 'kotlin-kapt'dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.core:core-ktx:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'

// Room components
def roomVersion = '2.2.1'
implementation "androidx.room:room-runtime:$roomVersion"
implementation "androidx.room:room-ktx:$roomVersion"
implementation "androidx.room:room-rxjava2:$roomVersion"
kapt "androidx.room:room-compiler:$roomVersion"

// Lifecycle components
def archLifecycleVersion = '2.2.0-beta01'
implementation "androidx.lifecycle:lifecycle-extensions:$archLifecycleVersion"
kapt "androidx.lifecycle:lifecycle-compiler:$archLifecycleVersion"

// RxJava
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
implementation 'io.reactivex.rxjava2:rxjava:2.2.12'

implementation "com.google.android.material:material:1.0.0"
}

Step 2: Buat Entities

Buat Entity / Model class Word

@Entity (tableName = "tb_word")
data class Word(
@PrimaryKey
@ColumnInfo(name = "word") val word: String
)
  • Anotate @Entity akan memberi tau room untuk membuat table database dengan nama tb_word
  • Untuk set primary key tambahkan anotate @Primary

Step 3: Buat Data Access Objects (DAOs)

Data Access Object pada dasarnya adalah object atau interface yang menyediakan akses ke database. DAO harus berupa interface class atau abstract class. Untuk membuat DAO kita perlu membuat interface class dan beri anotate @Dao

@Dao
interface WordDao {

@Query("select * from tb_word")
fun getAllWords(): LiveData<List<Word>>

@Insert
fun insertWord(word: Word)

@Update
fun updateWord(word: Word)
}

Step 4: Buat the Database

Buat WordDB class dan extends dengan RoomDatabase.

@Database(entities = [Word::class], version = 2)
abstract class WordDB: RoomDatabase() {
abstract fun wordDao(): WordDao

companion object {
@Volatile
private var INSTANCE: WordDB? = null

fun getDatabase(context: Context): WordDB {
val temp = INSTANCE
if(temp != null) return temp

synchronized(this){
val instance = Room.databaseBuilder(
context,
WordDB::class.java,
"word_database"
).build()
INSTANCE = instance
return instance
}
}
}
}

Setup RoomDatabase layer telah selesai

Step 5: Buat Repository

Langkah selanjutnya, membuat repository. Repository digunakan untuk memanajemen semua transaksi query yang harus di execute di thread yang berbeda

Buat file Extension, dan tambahkan kode berikut

private fun Completable.execute(scheduler: Scheduler = Schedulers.io(),
observeOn: Scheduler = AndroidSchedulers.mainThread()){
subscribeOn(scheduler).observeOn(observeOn).subscribe()
}

Buat class WordRepos

Step 6: Buat ViewModel

Buat class MainViewModel , viewmodel digunakan untuk menghandle semua transaksi antara repository dengan UI

class MainViewModel(application: Application) : AndroidViewModel(application) {
private val wordRepos: WordRepos

init {
val wordDao = WordDB.getDatabase(application).wordDao()
wordRepos = WordRepos(wordDao)
}

fun getAllWords(): LiveData<List<Word>> = wordRepos.getAllWord()

fun insertWord(word: Word){
wordRepos.insertWord(word)
}

fun updateWord(word: Word){
wordRepos.updateWord(word)
}
}

Step 7: Let’s finish this

  • Tambahkan kode berikut ke activity_main.xml
<RelativeLayout 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/et_word"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"/>

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_below="@id/et_word"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="24dp"
android:layout_marginBottom="24dp"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"/>

</RelativeLayout>
  • Buat adapter_word.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content">

<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:padding="8dp">

<TextView
android:id="@+id/wordId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"/>

<TextView
android:id="@+id/word"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

</LinearLayout>

</androidx.cardview.widget.CardView>

</LinearLayout>
  • Buat WordAdapter
  • Lalu tambahkan kode berikut di MainActivity
class MainActivity : AppCompatActivity() {

private lateinit var mAdapter: WordAdapter
private lateinit var viewModel: MainViewModel

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

viewModel = ViewModelProvider(this).get(MainViewModel::class.java)
fab.setOnClickListener {
viewModel.insertWord(Word(et_word.text.toString()))
et_word.setText("")
}
setupRecyclerView()
observeWord()
}

private fun setupRecyclerView(){
mAdapter = WordAdapter()
recycler.apply {
layoutManager = LinearLayoutManager(this@MainActivity)
adapter = mAdapter
}

mAdapter.setOnItemClickListener(object: OnAdapterClick{
override fun itemClick(word: Word) {
Toast.makeText(this@MainActivity, word.word, Toast.LENGTH_SHORT).show()
}
})
}

private fun observeWord(){
viewModel.getAllWords().observe(
this, Observer<List<Word>>{
mAdapter.setWordItemList(it)
})
}
}

Jalankan aplikasi, dan hasilnya akan seperti gambar berikut…

Selesai sudah article ini… semoga bermanfaat :D

Dimas Rangga

Written by

https://www.linkedin.com/in/derangga

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade