Android Kotlin Fundamentals 06.1: Tworzenie bazy danych sal

Te ćwiczenia są częścią kursu Android Kotlin Fundamentals. Skorzystaj z tego kursu, jeśli będziesz wykonywać kolejno kilka ćwiczeń z programowania. Wszystkie ćwiczenia z kursu są wymienione na stronie docelowej ćwiczeń z programowania na temat Kotlin.

Wstęp

Większość aplikacji ma dane, które trzeba zachować, nawet po zamknięciu aplikacji przez użytkownika. Na przykład może ona zapisywać playlistę, asortyment przedmiotów, zapisy wydatków i dochody, katalog gwiazdozbiorów czy dane o śnie. Zwykle do przechowywania trwałych danych używana jest baza danych.

Room to biblioteka baz danych, która jest częścią pakietu Jetpack na Androida. Usługa Room wiąże się z wieloma zadaniami związanymi z konfigurowaniem i konfigurowaniem bazy danych oraz umożliwia interakcję aplikacji z bazą danych za pomocą zwykłych wywołań funkcji. Pod maską Room znajduje się abstrakcja bazy danych bazy danych SQLite. RoomTerminologia stosowana w przypadku bardziej złożonych zapytań oraz składnia zapytań stosowana są w modelu SQLite'a.

Na obrazie poniżej widać, jak baza danych Room pasuje do ogólnej architektury zalecanej w tym kursie.

Co musisz wiedzieć

Pamiętaj:

  • Tworzenie podstawowego interfejsu użytkownika aplikacji na Androida
  • Używanie aktywności, fragmentów i widoków.
  • Przechodzenie między fragmentami i używanie Safe Args (wtyczki Gradle) do przekazywania danych między fragmentami.
  • Wyświetlanie modeli, fabryk modeli modeli urządzeń oraz LiveData i jego obserwatorów. Tematy tych komponentów architektury są omówione we wcześniejszej części kursu z programowania.
  • Podstawowa znajomość baz danych SQL i języka SQLite. Na stronie SQLite Primer znajdziesz krótkie omówienie lub odświeżenie informacji.

Czego się nauczysz

  • Jak utworzyć bazę danych Room i korzystać z niej w celu przechowywania danych.
  • Jak utworzyć klasę danych, która definiuje tabelę w bazie danych.
  • Sposób użycia obiektu dostępu do danych (DAO) do mapowania funkcji Kotlin na zapytania SQL.
  • Jak sprawdzić, czy baza danych działa.

Jakie zadania wykonasz:

  • Utwórz bazę danych Room z interfejsem danych dotyczących snu.
  • Przetestuj bazę danych przy użyciu dostarczonych testów.

W ramach tego ćwiczenia tworzysz bazę danych aplikacji, która monitoruje jakość snu. Aplikacja używa bazy danych do przechowywania danych o śnie.

Aplikacja ma 2 ekrany reprezentowane przez fragmenty, co widać na rysunku poniżej.

Pierwszy ekran (po lewej stronie) ma przyciski do włączania i wyłączania śledzenia. Na ekranie widoczne są wszystkie dane dotyczące snu użytkownika. Kliknięcie przycisku Wyczyść powoduje trwałe usunięcie wszystkich danych użytkownika zbieranych przez aplikację.

Na drugim ekranie (po prawej) możesz wybrać ocenę jakości snu. W aplikacji ocena jest wyrażana numerycznie. Na potrzeby programowania aplikacja wyświetla ikony twarzy i ich odpowiedniki liczbowe.

Proces użytkownika wygląda tak:

  • Użytkownik otwiera aplikację i wyświetla się ekran monitorowania snu.
  • Użytkownik klika przycisk Start. Rejestruje godzinę rozpoczęcia i wyświetla ją. Przycisk Start jest wyłączony, a przycisk Stop jest włączony.
  • Użytkownik klika przycisk Zatrzymaj. Rejestruje godzinę zakończenia i otwiera ekran jakości snu.
  • Użytkownik wybiera ikonę jakości snu. Ekran zostanie zamknięty, a na ekranie śledzenia pojawi się godzina zakończenia snu oraz jakość snu. Przycisk Stop jest wyłączony, a przycisk Start – włączony. Aplikacja jest gotowa na kolejną noc.
  • Przycisk Wyczyść jest włączony zawsze, gdy w bazie danych znajdują się dane. Gdy użytkownik kliknie przycisk Wyczyść, wszystkie jego dane zostaną usunięte bez możliwości ich odzyskania.

Ta aplikacja używa uproszczonej architektury, jak pokazano poniżej, w kontekście pełnej architektury. Aplikacja używa tylko tych komponentów:

  • Kontroler interfejsu
  • Wyświetl model i LiveData
  • baza danych pokoju;

Krok 1. Pobierz i uruchom aplikację startową

  1. Pobierz aplikację TrackMySleepQuality-Starter z GitHuba.
  2. Utwórz i uruchom aplikację. Aplikacja wyświetla interfejs dla fragmentu SleepTrackerFragment, ale nie zawiera danych. Przyciski nie reagują na dotknięcia.

Krok 2. Sprawdź aplikację startową

  1. Przyjrzyj się plikom Gradle:
  • Plik Gradle projektu
    W pliku build.gradle na poziomie projektu zwróć uwagę na zmienne określające wersje biblioteki. Wersje używane w aplikacji startowej dobrze ze sobą współgrają i działają dobrze z tą aplikacją. Gdy zakończysz ćwiczenia z Androida Studio, Android Studio może poprosić Cię o aktualizację niektórych wersji. To Ty decydujesz, czy chcesz zaktualizować wersje dostępne w aplikacji czy w nich pozostać. Jeśli napotkasz błędy kompilacji, spróbuj użyć kombinacji wersji biblioteki, których używa ostateczna aplikacja.
  • Plik Gradle modułu. Zwróć uwagę na podane zależności dla wszystkich bibliotek Jetpacka na Androida, w tym Room, i zależności od współprogramów.
  1. Zapoznaj się z pakietami i interfejsem. Ta aplikacja jest podzielona według funkcji. Pakiet zawiera pliki zastępcze, w których można umieścić kod w serii ćwiczeń z programowania.
  • Pakiet database na cały kod dotyczący bazy danych Room.
  • Pakiety sleepquality i sleeptracker zawierają fragment, widok modelu i widok modelu modelu dla każdego ekranu.
  1. Zajrzyj do pliku Util.kt, który zawiera funkcje pomagające wyświetlać dane dotyczące jakości snu. Część komentarzy jest skomentowana, bo odwołuje się do modelu widoku, który utworzysz później.
  2. Zajrzyj do folderu androidTest (SleepDatabaseTest.kt). Ten test pomoże Ci sprawdzić, czy baza danych działa zgodnie z oczekiwaniami.

Na urządzeniach z Androidem dane są przedstawiane w klasach danych, a uzyskiwane do nich dane są modyfikowane za pomocą wywołań funkcji. W świecie baz danych musisz jednak mieć jednostki i zapytania.

  • Element reprezentuje obiekt lub koncepcję i jej właściwości, które mają być przechowywane w bazie danych. Klasa encji definiuje tabelę, a każde wystąpienie tej klasy reprezentuje wiersz w tabeli. Każda usługa definiuje kolumnę. W Twojej aplikacji jednostka przechowuje informacje o nocy snu.
  • Zapytanie to żądanie danych lub informacji z tabeli bazy danych albo kombinacji tabel albo żądanie wykonania określonych danych. Typowe zapytania dotyczą pobierania, wstawiania i aktualizowania encji. Możesz na przykład zapytanie dla wszystkich zapisanych nocy snu posortowane według czasu rozpoczęcia.

Usługa Room wykona całą ciężką pracę, umożliwiając Ci przejście z klas danych w Kotlin do jednostek, które można przechowywać w tabelach SQLite, a także przez deklaracje funkcji do zapytań SQL.

Każdy element należy zdefiniować jako klasę danych z adnotacjami, a interakcje jako interfejs z adnotacjami – obiekt dostępu do danych (DAO). Room używa tych adnotacji z adnotacjami do tworzenia tabel w bazie danych oraz zapytań, które są w niej wykonywane.

Krok 1. Utwórz jednostkę SleepNight

W tym zadaniu definiujesz jedną noc snu jako klasę danych z adnotacjami.

W przypadku jednej nocy snu musisz zapisać godzinę jego rozpoczęcia i zakończenia oraz ocenę jakości.

I musisz go mieć, żeby zidentyfikować całą noc.

  1. W pakiecie database znajdź i otwórz plik SleepNight.kt.
  2. Utwórz klasę danych SleepNight z parametrami identyfikatora, godziną rozpoczęcia (w milisekundach), czasem zakończenia (w milisekundach) i numeryczną oceną jakości snu.
  • Musisz zainicjować plik sleepQuality, więc ustaw go na -1, co oznacza, że nie zebrano żadnych danych dotyczących jakości.
  • Musisz też zainicjować czas zakończenia. Ustaw czas rozpoczęcia, by wskazać, że godzina zakończenia nie została jeszcze zarejestrowana.
data class SleepNight(
       var nightId: Long = 0L,
       val startTimeMilli: Long = System.currentTimeMillis(),
       var endTimeMilli: Long = startTimeMilli,
       var sleepQuality: Int = -1
)
  1. Przed deklaracją klasy dodaj adnotacje @Entity. Nazwij tabelę daily_sleep_quality_table. Argument funkcji tableName jest opcjonalny, ale zalecany. Inne argumenty znajdziesz w dokumentacji.

    Jeśli pojawi się taka prośba, zaimportuj Entity i inne adnotacje z biblioteki androidx.
@Entity(tableName = "daily_sleep_quality_table")
data class SleepNight(...)
  1. Aby zidentyfikować nightId jako klucz podstawowy, oznacz właściwość nightId atrybutem @PrimaryKey. Ustaw parametr autoGenerate na true, by usługa Room generowała identyfikator dla każdego elementu. To gwarantuje, że identyfikator każdej nocy jest niepowtarzalny.
@PrimaryKey(autoGenerate = true)
var nightId: Long = 0L,...
  1. Dodaj do pozostałych właściwości @ColumnInfo. Dostosuj nazwy właściwości za pomocą parametrów, jak pokazano poniżej.
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. Utwórz i uruchom kod, aby upewnić się, że nie ma w nich błędów.

W tym zadaniu definiujesz obiekt dostępu do danych (DAO). W Androidzie DAO udostępnia wygodne metody wstawiania, usuwania i aktualizowania bazy danych.

Jeśli używasz bazy danych Room, tworzysz do niej zapytania, definiując i wywołując funkcje Kotlin w swoim kodzie. Te funkcje Kotlin są mapowane na zapytania SQL. Definiujesz te mapowania w DAO za pomocą adnotacji, a Room tworzy wymagany kod.

Działanie DAO definiuje się jako interfejs niestandardowy dostępu do bazy danych.

W przypadku popularnych operacji na bazach danych biblioteka Room udostępnia adnotacje ułatwiające (takie jak @Insert, @Delete czy @Update). W każdej z nich znajdziesz adnotację @Query. Możesz wpisać dowolne zapytanie obsługiwane przez SQLite.

Dodatkowo podczas tworzenia zapytań w Android Studio kompilator sprawdza, czy w zapytaniach SQL nie ma błędów składni.

W przypadku bazy danych monitorowania snu z ocenami snu musisz mieć możliwość:

  • Wstaw nowe noce.
  • Zaktualizuj istniejącą noc, by zaktualizować godzinę zakończenia i ocenę jakości.
  • Zdobądź konkretną noc na podstawie jej klucza.
  • Korzystaj ze wszystkich nocy, aby je wyświetlić.
  • Ostatniej nocy.
  • Usuń wszystkie wpisy w bazie danych.

Krok 1. Utwórz DAO SleepDatabase

  1. W pakiecie database otwórz SleepDatabaseDao.kt.
  2. Zauważ, że element interface SleepDatabaseDao jest oznaczony adnotacją @Dao. Wszystkie DAO muszą być oznaczone słowem kluczowym @Dao.
@Dao
interface SleepDatabaseDao {}
  1. Dodaj adnotację @Insert do treści interfejsu. Poniżej @Insert dodaj funkcję insert(), która jako wystąpienie argumentu używa Entity klasy SleepNight.

    To wszystko. Room wygeneruje cały kod niezbędny do wstawiania SleepNight do bazy danych. Gdy wywołujesz insert() z kodu Kotlin, Room wykonuje zapytanie SQL, aby wstawić ten element do bazy danych. (Uwaga: funkcję możesz nazwać w dowolny sposób).
@Insert
fun insert(night: SleepNight)
  1. Dodaj adnotację @Update z funkcją update() do jednej etykiety SleepNight. Uaktualniony element to ten, który ma ten sam klucz, co ten, który został przekazany. Możesz zaktualizować niektóre lub wszystkie właściwości elementu.
@Update
fun update(night: SleepNight)

W przypadku pozostałych funkcji nie ma adnotacji adnotacji, więc musisz użyć adnotacji @Query i zapytań SQL.

  1. Dodaj adnotację @Query z funkcją get(), która przyjmuje argument Long keyi zwraca wartość null SleepNight. W przypadku brakującego parametru pojawi się błąd.
@Query
fun get(key: Long): SleepNight?
  1. Zapytanie jest dodawane do adnotacji jako parametr ciągu. Dodaj parametr do @Query. Ustaw je jako String jako zapytanie SQL.
  • Wybierz wszystkie kolumny z daily_sleep_quality_table
  • WHERE nightId odpowiada argumentowi :key.

    Zwróć uwagę na :key. W zapytaniu używa się dwukropku, aby odwoływać się do argumentów funkcji.
("SELECT * from daily_sleep_quality_table WHERE nightId = :key")
  1. Dodaj kolejną zasadę @Query z funkcją clear() i zapytaniem SQLite do DELETE – wszystko od daily_sleep_quality_table. To zapytanie nie usuwa samej tabeli.

    Adnotacja @Delete usuwa 1 element. Możesz użyć parametru @Delete i przesłać listę nocy do usunięcia. Wada polega na tym, że musisz pobrać lub znać zawartość tabeli. Adnotacja @Delete świetnie nadaje się do usuwania konkretnych wpisów, ale nieskutecznie usuwa wszystkie wpisy z tabeli.
@Query("DELETE FROM daily_sleep_quality_table")
fun clear()
  1. Dodaj @Query do funkcji getTonight(). Aby funkcja mogła obsłużyć wielkość liter pustej tabeli, ustaw właściwość SleepNight zwracaną przez getTonight(). (Na początku tabela jest pusta, a dane są wyczyszczone).

    Aby pobrać z bazy danych „&tot"”, wpisz zapytanie SQLite, które zwraca pierwszy element listy wyników posortowanej według nightId w kolejności malejącej. Wartość LIMIT 1 pozwala zwrócić tylko jeden element.
@Query("SELECT * FROM daily_sleep_quality_table ORDER BY nightId DESC LIMIT 1")
fun getTonight(): SleepNight?
  1. Dodaj @Query za pomocą funkcji getAllNights():
  • Zapytanie SQL powinno zwrócić wszystkie kolumny z kolumny daily_sleep_quality_table w kolejności malejącej.
  • Poproś o getAllNights(), aby zwrócił listę SleepNight elementów jako LiveData. Room aktualizuje ten LiveData, co oznacza, że dane musisz pobrać tylko raz.
  • Konieczne może być zaimportowanie LiveData z androidx.lifecycle.LiveData.
@Query("SELECT * FROM daily_sleep_quality_table ORDER BY nightId DESC")
fun getAllNights(): LiveData<List<SleepNight>>
  1. Nie zobaczysz żadnych widocznych zmian, ale upewnij się, że aplikacja jest wolna od błędów.

W tym zadaniu tworzysz bazę danych Room, która korzysta z Entity i DAO utworzonych w poprzednim zadaniu.

Musisz utworzyć abstrakcyjną klasę właściciela bazy danych opatrzoną adnotacją @Database. Ta klasa ma jedną metodę, która tworzy instancję bazy danych, jeśli baza danych nie istnieje, lub zwraca odwołanie do istniejącej bazy danych.

Pobieranie bazy danych Room trochę się angażuje, dlatego zanim zaczniesz od kodu, wykonaj te czynności:

  • Utwórz klasę public abstract, którą ma extends RoomDatabase. Ta klasa służy do działania jako właściciel bazy danych. Klasa jest abstrakcyjna, ponieważ Room tworzy ją za Ciebie.
  • Dodaj do zajęć adnotacje @Database. W argumentach zadeklaruj encje dla bazy danych i ustaw numer wersji.
  • W obiekcie companion określ abstrakcyjną metodę lub właściwość, która zwraca SleepDatabaseDao. Room wygeneruje treść za Ciebie.
  • Możesz użyć tylko jednego wystąpienia bazy danych Room dla całej aplikacji, dlatego RoomDatabase powinien być pojedynczym tonem.
  • Utwórz bazę danych Room za pomocą kreatora, tylko jeśli baza danych nie istnieje. W przeciwnym razie wróć do istniejącej bazy danych.

Krok 1. Utwórz bazę danych

  1. W pakiecie database otwórz SleepDatabase.kt.
  2. Utwórz w pliku plik abstract o nazwie SleepDatabase z rozszerzeniem RoomDatabase.

    Dodaj do zajęć @Database.
@Database()
abstract class SleepDatabase : RoomDatabase() {}
  1. W przypadku brakujących elementów i parametrów wersji pojawi się błąd. Adnotacja @Database wymaga kilku argumentów, aby element Room mógł utworzyć bazę danych.
  • Prześlij SleepNight jako jedyny element z listy entities.
  • Ustaw version jako 1. Po każdej zmianie schematu musisz zwiększyć numer wersji.
  • Ustaw exportSchema na false, aby nie zapisywać kopii zapasowych historii wersji schematu.
entities = [SleepNight::class], version = 1, exportSchema = false
  1. Baza danych musi mieć informacje o DAO. W treści klasy zadeklaruj abstrakcyjną wartość, która zwraca SleepDatabaseDao. Możesz mieć wiele DAO.
abstract val sleepDatabaseDao: SleepDatabaseDao
  1. Poniżej zdefiniuj obiekt companion. Obiekt towarzyszący umożliwia klientom dostęp do metod tworzenia lub pobierania bazy danych bez tworzenia instancji klasy. Ponieważ jedynym celem tych zajęć jest dostarczenie bazy danych, nie ma powodu, aby tworzyć instancje.
 companion object {}
  1. W obiekcie companion zadeklaruj prywatną zmienną o wartości null INSTANCE dla bazy danych i zainicjuj ją dla null. Zmienna INSTANCE zachowuje odniesienie do bazy danych po jej utworzeniu. Pomaga to unikać wielokrotnego otwierania połączeń z bazą danych, co jest kosztowne.

Dodaj adnotację INSTANCE do @Volatile. Wartość zmiennej zmiennej nigdy nie będzie zapisywana w pamięci podręcznej, a wszystkie zapisy i odczyty będą wykonywane z pamięci głównej i z niej. Dzięki temu wartość w pliku INSTANCE jest zawsze aktualna i taka sama we wszystkich wątkach. Oznacza to, że zmiany wprowadzone w jednym wątku w wątku INSTANCE są natychmiast widoczne dla wszystkich innych wątków i nie występuje sytuacja, w której dwa wątki aktualizują każdy element tego samego elementu w pamięci podręcznej, co stanowi problem.

@Volatile
private var INSTANCE: SleepDatabase? = null
  1. Poniżej INSTANCE, pozostając w obiekcie companion, zdefiniuj getInstance()metodę z parametrem Context, którego będzie potrzebować kreator. Zwraca typ SleepDatabase. Zobaczysz błąd, ponieważ getInstance() nie zwraca jeszcze żadnych danych.
fun getInstance(context: Context): SleepDatabase {}
  1. W getInstance() dodaj blok synchronized{}. Przekaż plik this, aby uzyskać dostęp do kontekstu.

    W tym samym czasie wiele wątków może poprosić o instancję bazy danych, co spowoduje utworzenie 2 baz danych zamiast 1 wątku. Problem prawdopodobnie nie wystąpi w tej przykładowej aplikacji, ale jest to możliwe w przypadku bardziej złożonej aplikacji. Opakowanie kodu do pobrania bazy danych do synchronized oznacza, że tylko jeden wątek wykonania może jednocześnie wpisać ten blok kodu, dzięki czemu baza danych zostanie zainicjowana tylko raz.
synchronized(this) {}
  1. Skopiuj zsynchronizowaną wartość INSTANCE (w bloku) do zmiennej lokalnej instance. Pozwala to korzystać z funkcji inteligentnego przesyłania, która jest dostępna tylko w przypadku zmiennych lokalnych.
var instance = INSTANCE
  1. W obrębie bloku synchronized return instance na końcu bloku synchronized. Zignoruj błąd niedopasowania typu zwracania. Gdy skończysz, nigdy nie zwrócisz wartości null.
return instance
  1. Nad instrukcją return dodaj instrukcję if, aby sprawdzić, czy instance ma wartość NULL, co oznacza, że nie ma jeszcze bazy danych.
if (instance == null) {}
  1. Jeśli instance to null, użyj kreatora bazy danych, by uzyskać bazę danych. W treści instrukcji if wywołaj Room.databaseBuilder i podaj podany przez siebie kontekst, klasę bazy danych i nazwę bazy danych sleep_history_database. Aby usunąć błąd, trzeba będzie dodać strategię migracji oraz parametr build() opisany w poniższych krokach.
instance = Room.databaseBuilder(
                           context.applicationContext,
                           SleepDatabase::class.java,
                           "sleep_history_database")
  1. Dodaj wymaganą strategię migracji do konstruktora. Użyj właściwości .fallbackToDestructiveMigration().

    Zwykle należałoby przekazać obiekt migracji ze strategią migracji, na której zmienia się schemat. Obiekt migracji to obiekt, który określa, w jaki sposób zostaną przeniesione wszystkie wiersze ze starym schematem i przekonwertuj je na wiersze w nowym schemacie, aby żadne dane nie zostały utracone. Migracja wykracza poza zakres tych ćwiczeń. Prostym rozwiązaniem jest zniszczenie i odbudowanie bazy danych, co oznacza utratę danych.
.fallbackToDestructiveMigration()
  1. Na koniec zadzwoń do: .build().
.build()
  1. Przypisanie INSTANCE = instance jako ostatniego kroku w instrukcji if.
INSTANCE = instance
  1. Ostateczny kod powinien wyglądać tak:
@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. Utwórz i uruchom kod.

Masz teraz wszystkie gotowe elementy do pracy z bazą danych Room. Kod jest tworzony i uruchamiany, ale nie da się stwierdzić, czy faktycznie działa. To dobry moment, aby dodać kilka podstawowych testów.

Krok 2. Przetestuj bazę danych SleepData

Na tym etapie przeprowadzasz testy, aby sprawdzić, czy baza danych działa. Dzięki temu będziesz mieć pewność, że baza danych będzie działać, zanim ją utworzysz. Podane testy są podstawowe. W przypadku aplikacji w wersji produkcyjnej należałoby wykonać wszystkie funkcje i zapytania na DAO.

Aplikacja startowa zawiera folder androidTest. Ten folder androidTest zawiera testy jednostkowe, które obejmują instrumentację na Androidzie. Jest to świetny sposób na stwierdzenie, że testy wymagają platformy Android, więc testy muszą zostać przeprowadzone na urządzeniu fizycznym lub wirtualnym. Oczywiście możesz też tworzyć i uruchamiać testy całkowite, które nie wymagają korzystania z platformy Android.

  1. W Android Studio w folderze androidTest otwórz plik SleepDatabaseTest.
  2. Aby cofnąć usunięcie kodu, zaznacz go i naciśnij skrót klawiszowy Cmd+/ lub Control+/.
  3. Przyjrzyj się plikowi.

Poniżej znajdziesz krótki opis kodu testowego, ponieważ jest to kolejny fragment kodu, którego możesz użyć:

  • SleepDabaseTest to klasa testowa.
  • Adnotacja @RunWith identyfikuje uruchamiającego, czyli program, który konfiguruje i wykonuje testy.
  • Podczas konfiguracji funkcja z adnotacją @Before jest wykonywana i tworzy w SleepDatabase pamięć SleepDatabaseDao. "In-memory" oznacza, że ta baza danych nie jest zapisana w systemie plików i zostanie usunięta po przeprowadzeniu testów.
  • Poza tym podczas tworzenia bazy danych w pamięci kod wywołuje inną metodę charakterystyczną dla testu (allowMainThreadQueries). Domyślnie, gdy spróbujesz uruchomić zapytania w wątku głównym, pojawi się błąd. Ta metoda pozwala przeprowadzać testy na wątku głównym. Należy to robić tylko podczas testów.
  • W przypadku metody z adnotacją @Test tworzysz, wstawiasz i pobierasz element SleepNight, a następnie deklarujesz, że są takie same. Jeśli coś pójdzie nie tak, zgłoś wyjątek. W rzeczywistym teście byłoby wiele metod @Test.
  • Po zakończeniu testowania funkcja oznaczona jako @After jest wykonywana w celu zamknięcia bazy danych.
  1. Kliknij prawym przyciskiem myszy plik testowy w panelu Project (Projekt) i wybierz Run 'SleepDatabaseTest'.
  2. Po zakończeniu testów sprawdź w panelu SleepDatabaseTest, czy wszystkie testy zostały zaliczone.

Ponieważ wszystkie testy zaliczone, potwierdzają teraz kilka informacji:

  • Baza danych została utworzona prawidłowo.
  • Możesz wstawić SleepNight do bazy danych.
  • Możesz odzyskać SleepNight.
  • SleepNight ma prawidłową wartość jakości.

Projekt na Android Studio: TrackMySleepQualityRoomAndTesting

Podczas testowania bazy danych musisz skorzystać ze wszystkich metod zdefiniowanych w atrybucji DAO. Aby wykonać testy, dodaj i przeprowadź testy, aby wykorzystać pozostałe metody DAO.

  • Zdefiniuj tabele jako klasy danych oznaczone adnotacją @Entity. Zdefiniuj właściwości z adnotacjami @ColumnInfo w kolumnach tabel.
  • Zdefiniuj obiekt dostępu do danych (DAO) jako interfejs z adnotacją @Dao. DAO mapuje funkcje Kotlin na zapytania bazy danych.
  • Użyj adnotacji do zdefiniowania funkcji @Insert, @Delete i @Update.
  • Użyj adnotacji @Query z ciągiem zapytania SQLite jako parametru dla wszystkich innych zapytań.
  • Utwórz klasę abstrakcyjną z funkcją getInstance(), która zwraca bazę danych.
  • Użyj testów z instrumentacją, aby sprawdzić, czy baza danych i dzienna liczba użytkowników, którzy korzystają z DAI, działają zgodnie z oczekiwaniami. Przesłanych testów możesz użyć jako szablonu.

Kurs Udacity:

Dokumentacja Androida dla programistów:

Inne dokumenty i artykuły:

Ta sekcja zawiera listę możliwych zadań domowych dla uczniów, którzy pracują w ramach tego ćwiczenia w ramach kursu prowadzonego przez nauczyciela. To nauczyciel może wykonać te czynności:

  • W razie potrzeby przypisz zadanie domowe.
  • Poinformuj uczniów, jak przesyłać zadania domowe.
  • Oceń projekty domowe.

Nauczyciele mogą wykorzystać te sugestie tak długo, jak chcą lub chcą, i mogą przypisać dowolne zadanie domowe.

Jeśli samodzielnie wykonujesz te ćwiczenia z programowania, możesz sprawdzić swoją wiedzę w tych zadaniach domowych.

Odpowiedz na te pytania

Pytanie 1

Jak wskazać, że klasa reprezentuje element do zapisania w bazie danych Room?

  • Ustaw zajęcia jako przedłużone do DatabaseEntity.
  • Dodaj do zajęć adnotacje @Entity.
  • Dodaj do zajęć adnotacje @Database.
  • Ustaw klasę jako przedłużoną do RoomEntity i dodaj do niej tekst @Room.

Pytanie 2

DAO (obiekt dostępu do danych) to interfejs, którego Room używa do mapowania funkcji Kotlin na zapytania bazy danych.

Jak wskazać, że interfejs reprezentuje dostawcę usługi zarządzania urządzeniami mobilnymi dla bazy danych Room?

  • Rozszerz interfejs (RoomDAO).
  • Otwórz interfejs EntityDao i użyj metody DaoConnection().
  • Dodaj do interfejsu adnotacje: @Dao.
  • Dodaj do interfejsu adnotacje: @RoomConnection.

Pytanie 3

Które z poniższych stwierdzeń na temat bazy danych Room są prawdziwe? Zaznacz wszystkie pasujące odpowiedzi.

  • Możesz zdefiniować tabele dla bazy danych Room jako adnotacje danych z adnotacjami.
  • Jeśli zwrócisz LiveData z zapytania, Room zmieni wartość LiveData, jeśli LiveData się zmieni.
  • Każda baza danych Room musi mieć jedną, tylko DAO.
  • Aby zidentyfikować klasę jako bazę danych Room, ustaw ją jako podkategorię RoomDatabase i dodaj do niej komentarz za pomocą atrybutu @Database.

Pytanie 4

Których z tych adnotacji można użyć w interfejsie @Dao? Zaznacz wszystkie pasujące odpowiedzi.

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

Pytanie 5

Jak sprawdzić, czy baza danych działa? Wybierz wszystkie pasujące odpowiedzi.

  • Napisz testy z instrumentacją.
  • Zapisuj i uruchamiaj aplikację, dopóki nie wyświetlą się dane.
  • Zastąp wywołania metody w interfejsie DAO wywołaniami metod równorzędnych w klasie Entity.
  • Uruchom funkcję verifyDatabase() udostępnioną przez bibliotekę Room.

Przejdź do następnej lekcji: 6.2 korutyny i pokój

Linki do innych ćwiczeń z programowania w tym kursie znajdziesz na stronie docelowej z ćwiczeniami z podstaw Androida Kotlin.