Dasar-Dasar Android Kotlin 06.1: Membuat database Room

Codelab ini adalah bagian dari kursus Dasar-Dasar Android Kotlin. Anda akan mendapatkan manfaat maksimal dari kursus ini jika menyelesaikan codelab secara berurutan. Semua codelab kursus tercantum di halaman landing codelab Dasar-Dasar Android Kotlin.

Pengantar

Sebagian besar aplikasi memiliki data yang perlu disimpan, bahkan setelah pengguna menutup aplikasi. Misalnya, aplikasi dapat menyimpan playlist, inventaris item game, catatan pengeluaran dan pendapatan, katalog konstelasi, atau data tidur dari waktu ke waktu. Biasanya, Anda akan menggunakan database untuk menyimpan data persisten.

Room adalah library database yang merupakan bagian dari Android Jetpack. Room menangani banyak tugas penyiapan dan konfigurasi database, serta memungkinkan aplikasi berinteraksi dengan database menggunakan panggilan fungsi biasa. Di balik layar, Room adalah lapisan abstraksi di atas database SQLite. Terminologi Room dan sintaksis kueri untuk kueri yang lebih kompleks mengikuti model SQLite.

Gambar di bawah menunjukkan kesesuaian database Room dengan arsitektur keseluruhan yang direkomendasikan dalam kursus ini.

Yang harus sudah Anda ketahui

Anda harus memahami:

  • Membangun antarmuka pengguna (UI) dasar untuk aplikasi Android
  • Menggunakan aktivitas, fragmen, dan tampilan.
  • Bernavigasi antar-fragmen dan menggunakan Safe Args (plugin Gradle) untuk meneruskan data antar-fragmen.
  • Model tampilan, factory model tampilan, dan LiveData serta pengamatnya. Topik Komponen Arsitektur ini dibahas dalam codelab sebelumnya di kursus ini.
  • Pemahaman dasar tentang database SQL dan bahasa SQLite. Lihat Pengantar SQLite untuk ringkasan atau penyegaran cepat.

Yang akan Anda pelajari

  • Cara membuat dan berinteraksi dengan database Room untuk menyimpan data.
  • Cara membuat class data yang menentukan tabel dalam database.
  • Cara menggunakan objek akses data (DAO) untuk memetakan fungsi Kotlin ke kueri SQL.
  • Cara menguji apakah database Anda berfungsi.

Yang akan Anda lakukan

  • Buat database Room dengan antarmuka untuk data tidur malam.
  • Uji database menggunakan pengujian yang disediakan.

Dalam codelab ini, Anda akan membuat bagian database dari aplikasi yang melacak kualitas tidur. Aplikasi ini menggunakan database untuk menyimpan data tidur dari waktu ke waktu.

Aplikasi memiliki dua layar, yang diwakili oleh fragmen, seperti yang ditunjukkan pada gambar di bawah.

Layar pertama, yang ditampilkan di sebelah kiri, memiliki tombol untuk memulai dan menghentikan pelacakan. Layar menampilkan semua data tidur pengguna. Tombol Hapus akan menghapus semua data yang telah dikumpulkan aplikasi untuk pengguna secara permanen.

Layar kedua, yang ditampilkan di sebelah kanan, adalah untuk memilih rating kualitas tidur. Di aplikasi, rating ditampilkan secara numerik. Untuk tujuan pengembangan, aplikasi menampilkan ikon wajah dan nilai numeriknya.

Alur pengguna adalah sebagai berikut:

  • Pengguna membuka aplikasi dan melihat layar pelacakan tidur.
  • Pengguna mengetuk tombol Mulai. Tindakan ini akan merekam waktu mulai dan menampilkannya. Tombol Mulai dinonaktifkan, dan tombol Berhenti diaktifkan.
  • Pengguna mengetuk tombol Berhenti. Tindakan ini akan mencatat waktu berakhir dan membuka layar kualitas tidur.
  • Pengguna memilih ikon kualitas tidur. Layar ditutup, dan layar pelacakan menampilkan waktu berakhirnya tidur dan kualitas tidur. Tombol Berhenti dinonaktifkan dan tombol Mulai diaktifkan. Aplikasi siap untuk malam lainnya.
  • Tombol Hapus diaktifkan setiap kali ada data dalam database. Saat pengguna mengetuk tombol Hapus, semua datanya akan dihapus tanpa dapat dipulihkan—tidak ada pesan "Apakah Anda yakin?".

Aplikasi ini menggunakan arsitektur yang disederhanakan, seperti yang ditunjukkan di bawah dalam konteks arsitektur lengkap. Aplikasi hanya menggunakan komponen berikut:

  • Pengontrol UI
  • Lihat model dan LiveData
  • Database Room

Langkah 1: Download dan jalankan aplikasi awal

  1. Download aplikasi TrackMySleepQuality-Starter dari GitHub.
  2. Build dan jalankan aplikasi. Aplikasi menampilkan UI untuk fragmen SleepTrackerFragment, tetapi tidak ada data. Tombol tidak merespons ketukan.

Langkah 2: Periksa aplikasi awal

  1. Lihat file Gradle:
  • File Gradle project
    Dalam file build.gradle tingkat project, perhatikan variabel yang menentukan versi library. Versi yang digunakan dalam aplikasi starter berfungsi dengan baik bersama-sama, dan berfungsi dengan baik dengan aplikasi ini. Saat Anda menyelesaikan codelab ini, Android Studio mungkin meminta Anda untuk mengupdate beberapa versi. Anda dapat memilih apakah ingin mengupdate atau tetap menggunakan versi yang ada di aplikasi. Jika Anda mengalami error kompilasi yang "aneh", coba gunakan kombinasi versi library yang digunakan oleh aplikasi solusi akhir.
  • File Gradle modul. Perhatikan dependensi yang disediakan untuk semua library Android Jetpack, termasuk Room, dan dependensi untuk coroutine.
  1. Lihat paket dan UI. Aplikasi disusun berdasarkan fungsi. Paket ini berisi file placeholder tempat Anda akan menambahkan kode di seluruh rangkaian codelab ini.
  • Paket database, untuk semua kode yang terkait dengan database Room.
  • Paket sleepquality dan sleeptracker berisi fragmen, model tampilan, dan factory model tampilan untuk setiap layar.
  1. Lihat file Util.kt, yang berisi fungsi untuk membantu menampilkan data kualitas tidur. Beberapa kode diberi komentar karena mereferensikan model tampilan yang akan Anda buat nanti.
  2. Lihat folder androidTest (SleepDatabaseTest.kt). Anda akan menggunakan pengujian ini untuk memverifikasi bahwa database berfungsi seperti yang diinginkan.

Di Android, data direpresentasikan dalam class data, dan data diakses serta dimodifikasi menggunakan panggilan fungsi. Namun, dalam dunia database, Anda memerlukan entitas dan kueri.

  • Entitas menampilkan objek atau konsep beserta propertinya untuk disimpan dalam database. Class entitas menentukan tabel, dan setiap instance dari class tersebut mewakili baris dalam tabel. Setiap properti menentukan kolom. Di aplikasi Anda, entity akan menyimpan informasi tentang tidur malam.
  • Kueri adalah permintaan untuk mengakses data atau informasi dari tabel database atau kombinasi tabel, atau permintaan untuk melakukan tindakan pada data. Kueri umum adalah untuk mendapatkan, menyisipkan, dan memperbarui entity. Misalnya, Anda dapat membuat kueri untuk semua malam tidur yang tercatat, diurutkan berdasarkan waktu mulai.

Room melakukan semua pekerjaan berat untuk Anda, mulai dari class data Kotlin hingga entity yang dapat disimpan dalam tabel SQLite, dan dari deklarasi fungsi hingga kueri SQL.

Anda harus menentukan setiap entity sebagai class data yang dianotasi, dan interaksi sebagai antarmuka yang dianotasi, yaitu objek akses data (DAO). Room menggunakan class beranotasi ini untuk membuat tabel dalam database, dan kueri yang beroperasi pada database.

Langkah 1: Buat entity SleepNight

Dalam tugas ini, Anda akan menentukan satu malam tidur sebagai class data yang dianotasi.

Untuk satu malam tidur, Anda perlu mencatat waktu mulai, waktu berakhir, dan rating kualitas.

Anda juga memerlukan ID untuk mengidentifikasi malam secara unik.

  1. Dalam paket database, temukan dan buka file SleepNight.kt.
  2. Buat class data SleepNight dengan parameter untuk ID, waktu mulai (dalam milidetik), waktu berakhir (dalam milidetik), dan rating kualitas tidur numerik.
  • Anda harus menginisialisasi sleepQuality, jadi tetapkan ke -1, yang menunjukkan bahwa tidak ada data kualitas yang telah dikumpulkan.
  • Anda juga harus melakukan inisialisasi waktu berakhir. Setel ke waktu mulai untuk menandakan bahwa waktu berakhir belum direkam.
data class SleepNight(
       var nightId: Long = 0L,
       val startTimeMilli: Long = System.currentTimeMillis(),
       var endTimeMilli: Long = startTimeMilli,
       var sleepQuality: Int = -1
)
  1. Sebelum deklarasi class, beri anotasi pada class data dengan @Entity. Beri nama tabel daily_sleep_quality_table. Argumen untuk tableName bersifat opsional, tetapi direkomendasikan. Anda dapat mencari argumen lain dalam dokumentasi.

    Jika diminta, impor Entity dan semua anotasi lainnya dari library androidx.
@Entity(tableName = "daily_sleep_quality_table")
data class SleepNight(...)
  1. Untuk mengidentifikasi nightId sebagai kunci utama, beri anotasi pada properti nightId dengan @PrimaryKey. Setel parameter autoGenerate ke true sehingga Room menghasilkan ID untuk setiap entity. Hal ini menjamin bahwa ID untuk setiap malam bersifat unik.
@PrimaryKey(autoGenerate = true)
var nightId: Long = 0L,...
  1. Anotasikan properti yang tersisa dengan @ColumnInfo. Sesuaikan nama properti menggunakan parameter seperti yang ditunjukkan di bawah ini.
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey

@Entity(tableName = "daily_sleep_quality_table")
data class SleepNight(
       @PrimaryKey(autoGenerate = true)
       var nightId: Long = 0L,

       @ColumnInfo(name = "start_time_milli")
       val startTimeMilli: Long = System.currentTimeMillis(),

       @ColumnInfo(name = "end_time_milli")
       var endTimeMilli: Long = startTimeMilli,

       @ColumnInfo(name = "quality_rating")
       var sleepQuality: Int = -1
)
  1. Build dan jalankan kode Anda untuk memastikan tidak ada error.

Dalam tugas ini, Anda akan menentukan objek akses data (DAO). Di Android, DAO menyediakan metode praktis untuk menyisipkan, menghapus, dan memperbarui database.

Saat menggunakan database Room, Anda membuat kueri database dengan menentukan dan memanggil fungsi Kotlin dalam kode Anda. Fungsi Kotlin ini dipetakan ke kueri SQL. Anda menentukan pemetaan tersebut di DAO menggunakan anotasi, dan Room membuat kode yang diperlukan.

Anggap DAO sebagai penentuan antarmuka kustom untuk mengakses database Anda.

Untuk operasi database umum, library Room menyediakan anotasi kemudahan, seperti @Insert, @Delete, dan @Update. Untuk lainnya, terdapat anotasi @Query. Anda dapat menulis kueri apa pun yang didukung oleh SQLite.

Sebagai bonus tambahan, saat Anda membuat kueri di Android Studio, compiler akan memeriksa kueri SQL untuk menemukan error sintaksis.

Untuk database pelacak tidur malam, Anda harus dapat melakukan hal berikut:

  • Sisipkan malam baru.
  • Perbarui malam yang ada untuk memperbarui waktu berakhir dan rating kualitas.
  • Mendapatkan malam tertentu berdasarkan kuncinya.
  • Dapatkan semua malam, sehingga Anda dapat menampilkannya.
  • Mendapatkan malam terbaru.
  • Hapus semua entri di database.

Langkah 1: Buat DAO SleepDatabase

  1. Di paket database, buka SleepDatabaseDao.kt.
  2. Perhatikan bahwa interface SleepDatabaseDao dianotasi dengan @Dao. Semua DAO harus diberi anotasi dengan kata kunci @Dao.
@Dao
interface SleepDatabaseDao {}
  1. Di dalam isi antarmuka, tambahkan anotasi @Insert. Di bawah @Insert, tambahkan fungsi insert() yang menggunakan instance class Entity SleepNight sebagai argumennya.

    Selesai. Room akan menghasilkan semua kode yang diperlukan untuk memasukkan SleepNight ke dalam database. Saat Anda memanggil insert() dari kode Kotlin, Room akan menjalankan kueri SQL untuk memasukkan entity ke dalam database. (Catatan: Anda dapat memanggil fungsi apa pun yang Anda inginkan.)
@Insert
fun insert(night: SleepNight)
  1. Tambahkan anotasi @Update dengan fungsi update() untuk satu SleepNight. Entity yang diperbarui adalah entity yang memiliki kunci yang sama dengan entity yang diteruskan. Anda dapat memperbarui beberapa atau semua properti lainnya dari entity tersebut.
@Update
fun update(night: SleepNight)

Tidak ada anotasi kemudahan untuk fungsi yang tersisa, sehingga Anda harus menggunakan anotasi @Query dan menyediakan kueri SQLite.

  1. Tambahkan anotasi @Query dengan fungsi get() yang menggunakan argumen Long key dan menampilkan SleepNight yang dapat bernilai null. Anda akan melihat error untuk parameter yang tidak ada.
@Query
fun get(key: Long): SleepNight?
  1. Kueri diberikan sebagai parameter string ke anotasi. Tambahkan parameter ke @Query. Jadikan String sebagai kueri SQLite.
  • Pilih semua kolom dari daily_sleep_quality_table
  • WHERE nightId cocok dengan argumen :key.

    Perhatikan :key. Anda dapat menggunakan notasi titik dua di kueri untuk mereferensikan argumen dalam fungsi.
("SELECT * from daily_sleep_quality_table WHERE nightId = :key")
  1. Tambahkan @Query lain dengan fungsi clear() dan kueri SQLite untuk DELETE semuanya dari daily_sleep_quality_table. Kueri ini tidak menghapus tabel itu sendiri.

    Anotasi @Delete menghapus satu item, dan Anda dapat menggunakan @Delete serta memberikan daftar malam yang akan dihapus. Kekurangannya adalah Anda perlu mengambil atau mengetahui apa yang ada dalam tabel. Anotasi @Delete sangat bagus untuk menghapus entri tertentu, tetapi tidak efisien untuk menghapus semua entri dari tabel.
@Query("DELETE FROM daily_sleep_quality_table")
fun clear()
  1. Tambahkan @Query dengan fungsi getTonight(). Buat SleepNight yang ditampilkan oleh getTonight() nullable, sehingga fungsi dapat menangani kasus saat tabel kosong. (Tabel kosong di awal, dan setelah data dihapus.)

    Untuk mendapatkan "malam ini" dari database, tulis kueri SQLite yang menampilkan elemen pertama dari daftar hasil yang diurutkan berdasarkan nightId dalam urutan menurun. Gunakan LIMIT 1 untuk menampilkan hanya satu elemen.
@Query("SELECT * FROM daily_sleep_quality_table ORDER BY nightId DESC LIMIT 1")
fun getTonight(): SleepNight?
  1. Tambahkan @Query dengan fungsi getAllNights():
  • Minta kueri SQLite untuk menampilkan semua kolom dari daily_sleep_quality_table yang diurutkan dalam urutan menurun.
  • Minta getAllNights() menampilkan daftar entity SleepNight sebagai LiveData. Room terus memperbarui LiveData ini, yang berarti Anda hanya perlu mendapatkan data secara eksplisit satu kali.
  • Anda mungkin perlu mengimpor LiveData dari androidx.lifecycle.LiveData.
@Query("SELECT * FROM daily_sleep_quality_table ORDER BY nightId DESC")
fun getAllNights(): LiveData<List<SleepNight>>
  1. Meskipun Anda tidak akan melihat perubahan apa pun yang terlihat, jalankan aplikasi untuk memastikan tidak ada error.

Dalam tugas ini, Anda akan membuat database Room yang menggunakan Entity dan DAO yang telah dibuat di tugas sebelumnya.

Anda perlu membuat class holder database abstrak, yang dianotasi dengan @Database. Class ini memiliki satu metode yang dapat membuat instance database jika database tidak ada, atau menampilkan referensi ke database yang ada.

Mendapatkan database Room agak rumit, jadi berikut adalah proses umumnya sebelum Anda memulai dengan kode:

  • Buat class public abstract yang extends RoomDatabase. Class ini berfungsi sebagai holder database. Class bersifat abstrak, karena Room yang akan membuatkan implementasi untuk Anda.
  • Anotasikan class dengan @Database. Dalam argumen, deklarasikan entity untuk database dan tetapkan nomor versinya.
  • Di dalam objek companion, tentukan metode atau properti abstrak yang menampilkan SleepDatabaseDao. Room akan membuat isi pesan untuk Anda.
  • Anda hanya memerlukan satu instance database Room untuk seluruh aplikasi, sehingga jadikan RoomDatabase sebuah singleton.
  • Gunakan builder database Room untuk membuat database hanya jika database tidak ada. Jika tidak, tampilkan database yang ada.

Langkah 1: Buat database

  1. Di paket database, buka SleepDatabase.kt.
  2. Dalam file, buat class abstract bernama SleepDatabase yang memperluas RoomDatabase.

    Anotasikan class dengan @Database.
@Database()
abstract class SleepDatabase : RoomDatabase() {}
  1. Anda akan melihat error untuk parameter entitas dan versi yang tidak ada. Anotasi @Database memerlukan beberapa argumen, sehingga Room dapat membuat database.
  • Berikan SleepNight sebagai satu-satunya item dengan daftar entities.
  • Tetapkan version sebagai 1. Setiap kali mengubah skema, Anda harus meningkatkan nomor versinya.
  • Setel exportSchema ke false agar tidak menyimpan cadangan histori versi skema.
entities = [SleepNight::class], version = 1, exportSchema = false
  1. Database harus mengetahui DAO. Di dalam isi class, deklarasikan nilai abstrak yang menampilkan SleepDatabaseDao. Anda dapat memiliki beberapa DAO.
abstract val sleepDatabaseDao: SleepDatabaseDao
  1. Di bawahnya, tentukan objek companion. Objek pendamping memungkinkan klien mengakses metode untuk membuat atau mendapatkan database tanpa membuat instance class. Karena satu-satunya tujuan class ini adalah untuk menyediakan database, tidak ada alasan untuk membuat instance-nya.
 companion object {}
  1. Di dalam objek companion, deklarasikan variabel nullable pribadi INSTANCE untuk database lalu inisialisasikan ke null. Variabel INSTANCE akan menyimpan referensi ke database setelah salah satunya dibuat. Hal ini membantu Anda menghindari pembukaan koneksi ke database secara berulang, yang mahal.

Anotasikan INSTANCE dengan @Volatile. Nilai variabel yang tidak stabil tidak akan disimpan dalam cache, dan semua penulisan dan pembacaan akan dilakukan ke dan dari memori utama. Hal ini akan membantu memastikan nilai INSTANCE selalu terbaru dan sama untuk semua thread eksekusi. Hal ini berarti perubahan yang dibuat oleh satu thread ke INSTANCE akan langsung terlihat oleh semua thread lainnya, dan Anda tidak akan mengalami situasi di mana, misalnya, dua thread masing-masing memperbarui entity yang sama dalam cache, yang akan menimbulkan masalah.

@Volatile
private var INSTANCE: SleepDatabase? = null
  1. Di bawah INSTANCE, saat masih berada di dalam objek companion, tentukan metode getInstance() dengan parameter Context yang diperlukan builder database. Tampilkan jenis SleepDatabase. Anda akan melihat error karena getInstance() belum menampilkan apa pun.
fun getInstance(context: Context): SleepDatabase {}
  1. Di dalam getInstance(), tambahkan blok synchronized{}. Teruskan this sehingga Anda dapat mengakses konteks.

    Beberapa thread berpotensi meminta instance database secara bersamaan sehingga menghasilkan dua database, bukan satu. Masalah ini kemungkinan tidak akan terjadi di aplikasi contoh ini, tetapi bisa terjadi pada aplikasi yang lebih kompleks. Dengan menggabungkan kode untuk mendapatkan database ke dalam synchronized berarti hanya satu thread eksekusi dalam satu waktu yang dapat memasukkan blok kode ini, yang memastikan bahwa database hanya diinisialisasi sekali.
synchronized(this) {}
  1. Di dalam blok yang disinkronkan, salin nilai INSTANCE saat ini ke variabel lokal instance. Hal ini dilakukan untuk memanfaatkan smart cast, yang hanya tersedia untuk variabel lokal.
var instance = INSTANCE
  1. Di dalam blok synchronized, return instance di akhir blok synchronized. Abaikan error ketidakcocokan jenis yang ditampilkan; Anda tidak akan pernah menampilkan null setelah selesai.
return instance
  1. Di atas pernyataan return, tambahkan pernyataan if untuk memeriksa apakah instance null, yaitu belum ada database.
if (instance == null) {}
  1. Jika instance adalah null, gunakan builder database untuk mendapatkan database. Di bagian isi pernyataan if, panggil Room.databaseBuilder dan berikan konteks yang Anda teruskan, class database, dan nama untuk database, sleep_history_database. Untuk menghapus error ini, Anda harus menambahkan strategi migrasi dan build() di langkah berikut.
instance = Room.databaseBuilder(
                           context.applicationContext,
                           SleepDatabase::class.java,
                           "sleep_history_database")
  1. Tambahkan strategi migrasi yang diperlukan ke builder. Gunakan .fallbackToDestructiveMigration().

    Biasanya, Anda harus memberikan objek migrasi dengan strategi migrasi saat skema berubah. Objek migrasi adalah objek yang menentukan cara Anda mengambil semua baris dengan skema lama dan mengonversinya menjadi baris dalam skema yang baru, sehingga tidak ada data yang hilang. Migrasi berada di luar cakupan codelab ini. Solusi yang mudah adalah dengan menghancurkan dan membuat ulang database yang berarti data tersebut akan hilang.
.fallbackToDestructiveMigration()
  1. Terakhir, panggil .build().
.build()
  1. Tetapkan INSTANCE = instance sebagai langkah terakhir dalam pernyataan if.
INSTANCE = instance
  1. Kode final akan terlihat seperti ini:
@Database(entities = [SleepNight::class], version = 1, exportSchema = false)
abstract class SleepDatabase : RoomDatabase() {

   abstract val sleepDatabaseDao: SleepDatabaseDao

   companion object {

       @Volatile
       private var INSTANCE: SleepDatabase? = null

       fun getInstance(context: Context): SleepDatabase {
           synchronized(this) {
               var instance = INSTANCE

               if (instance == null) {
                   instance = Room.databaseBuilder(
                           context.applicationContext,
                           SleepDatabase::class.java,
                           "sleep_history_database"
                   )
                           .fallbackToDestructiveMigration()
                           .build()
                   INSTANCE = instance
               }
               return instance
           }
       }
   }
}
  1. Bangun dan jalankan kode Anda.

Sekarang Anda memiliki semua elemen penyusun untuk menggunakan database Room. Kode ini dikompilasi dan dijalankan, tetapi Anda tidak dapat mengetahui apakah kode tersebut benar-benar berfungsi. Jadi, ini adalah saat yang tepat untuk menambahkan beberapa pengujian dasar.

Langkah 2: Uji SleepDatabase

Pada langkah ini, Anda menjalankan pengujian yang disediakan untuk memverifikasi bahwa database Anda berfungsi. Hal ini membantu memastikan bahwa database berfungsi sebelum Anda membangunnya. Pengujian yang diberikan bersifat dasar. Untuk aplikasi produksi, Anda akan menjalankan semua fungsi dan kueri di semua DAO.

Aplikasi awal berisi folder androidTest. Folder androidTest ini berisi pengujian unit yang melibatkan instrumentasi Android, yang merupakan cara canggih untuk mengatakan bahwa pengujian memerlukan framework Android, sehingga Anda perlu menjalankan pengujian di perangkat fisik atau virtual. Tentu saja, Anda juga dapat membuat dan menjalankan pengujian unit murni yang tidak melibatkan framework Android.

  1. Di Android Studio, pada folder androidTest, buka file SleepDatabaseTest.
  2. Untuk menghapus komentar pada kode, pilih semua kode yang diberi komentar dan tekan pintasan keyboard Cmd+/ atau Control+/.
  3. Lihat file.

Berikut ringkasan singkat kode pengujian, karena kode ini adalah bagian kode lain yang dapat Anda gunakan kembali:

  • SleepDabaseTest adalah class pengujian.
  • Anotasi @RunWith mengidentifikasi runner pengujian, yaitu program yang menyiapkan dan menjalankan pengujian.
  • Selama penyiapan, fungsi yang dianotasi dengan @Before akan dieksekusi, dan fungsi tersebut akan membuat SleepDatabase dalam memori dengan SleepDatabaseDao. "Dalam memori" berarti bahwa database ini tidak disimpan di sistem file dan akan dihapus setelah pengujian dijalankan.
  • Selain itu, saat membangun database dalam memori, kode memanggil metode khusus pengujian lainnya, allowMainThreadQueries. Secara default, Anda akan mendapatkan error jika mencoba menjalankan kueri di thread utama. Metode ini memungkinkan Anda menjalankan pengujian di thread utama, yang hanya boleh Anda lakukan selama pengujian.
  • Dalam metode pengujian yang dianotasi dengan @Test, Anda membuat, menyisipkan, dan mengambil SleepNight, serta menegaskan bahwa keduanya sama. Jika ada masalah, berikan pengecualian. Dalam pengujian sebenarnya, Anda akan memiliki beberapa metode @Test .
  • Setelah pengujian selesai, fungsi yang dianotasi dengan @After akan dieksekusi untuk menutup database.
  1. Klik kanan pada file pengujian di panel Project, lalu pilih Run 'SleepDatabaseTest'.
  2. Setelah pengujian berjalan, pastikan di panel SleepDatabaseTest bahwa semua pengujian telah lulus.

Karena semua pengujian berhasil, Anda sekarang mengetahui beberapa hal:

  • Database dibuat dengan benar.
  • Anda dapat menyisipkan SleepNight ke dalam database.
  • Anda dapat mendapatkan kembali SleepNight.
  • SleepNight memiliki nilai yang benar untuk kualitas.

Project Android Studio: TrackMySleepQualityRoomAndTesting

Saat menguji database, Anda harus menjalankan semua metode yang ditentukan dalam DAO. Untuk menyelesaikan pengujian, tambahkan dan jalankan pengujian untuk melatih metode DAO lainnya.

  • Tentukan tabel Anda sebagai class data yang dianotasi dengan @Entity. Tentukan properti yang dianotasi dengan @ColumnInfo sebagai kolom dalam tabel.
  • Tentukan objek akses data (DAO) sebagai antarmuka yang dianotasi dengan @Dao. DAO memetakan fungsi Kotlin ke kueri database.
  • Gunakan anotasi untuk menentukan fungsi @Insert, @Delete, dan @Update.
  • Gunakan anotasi @Query dengan string kueri SQLite sebagai parameter untuk kueri lainnya.
  • Buat class abstrak yang memiliki fungsi getInstance() yang menampilkan database.
  • Gunakan pengujian berinstrumen untuk menguji apakah database dan DAO Anda berfungsi seperti yang diharapkan. Anda dapat menggunakan pengujian yang disediakan sebagai template.

Kursus Udacity:

Dokumentasi Developer Android:

Dokumentasi dan artikel lainnya:

Bagian ini mencantumkan kemungkinan tugas pekerjaan rumah untuk siswa yang mengerjakan codelab ini sebagai bagian dari kursus yang dipimpin oleh instruktur. Instruktur menentukan hal berikut:

  • Memberikan pekerjaan rumah jika diperlukan.
  • Memberi tahu siswa cara mengirimkan tugas pekerjaan rumah.
  • Memberi nilai tugas pekerjaan rumah.

Instruktur bisa menggunakan saran ini sesuai kebutuhan, dan bebas menugaskan pekerjaan rumah lain yang dirasa cocok.

Jika Anda menyelesaikan codelab ini sendiri, gunakan tugas pekerjaan rumah ini untuk menguji pengetahuan Anda.

Jawab pertanyaan-pertanyaan berikut

Pertanyaan 1

Bagaimana cara Anda menunjukkan bahwa class mewakili entity untuk disimpan di database Room?

  • Buat class memperluas DatabaseEntity.
  • Anotasikan class dengan @Entity.
  • Anotasikan class dengan @Database.
  • Buat class memperluas RoomEntity dan juga menganotasi class dengan @Room.

Pertanyaan 2

DAO (objek akses data) adalah antarmuka yang digunakan Room untuk memetakan fungsi Kotlin ke kueri database.

Bagaimana cara Anda menunjukkan bahwa antarmuka mewakili DAO untuk database Room?

  • Buat antarmuka memperluas RoomDAO.
  • Buat antarmuka memperluas EntityDao, lalu terapkan metode DaoConnection().
  • Anotasi antarmuka dengan @Dao.
  • Anotasi antarmuka dengan @RoomConnection.

Pertanyaan 3

Manakah dari pernyataan berikut yang benar tentang database Room? Pilih semua yang sesuai.

  • Anda dapat menentukan tabel untuk database Room sebagai class data yang dianotasi.
  • Jika Anda menampilkan LiveData dari kueri, Room akan terus memperbarui LiveData untuk Anda jika LiveData berubah.
  • Setiap database Room harus memiliki satu, dan hanya satu, DAO.
  • Untuk mengidentifikasi class sebagai database Room, jadikan class tersebut sebagai subclass dari RoomDatabase dan beri anotasi dengan @Database.

Pertanyaan 4

Manakah dari anotasi berikut yang dapat Anda gunakan di antarmuka @Dao? Pilih semua yang sesuai.

  • @Get
  • @Update
  • @Insert
  • @Query

Pertanyaan 5

Bagaimana cara memastikan bahwa database Anda berfungsi? Pilih semua yang sesuai.

  • Menulis pengujian berinstrumen.
  • Lanjutkan penulisan dan jalankan aplikasi hingga menampilkan data.
  • Mengganti panggilan ke metode di antarmuka DAO dengan panggilan ke metode setara di class Entity.
  • Jalankan fungsi verifyDatabase() yang disediakan oleh library Room.

Lanjutkan ke pelajaran berikutnya: 6.2 Coroutine dan Room

Untuk link ke codelab lain dalam kursus ini, lihat halaman landing codelab Dasar-Dasar Android Kotlin.