The Sleep tracker app for lesson 6 of the Udacity: Developing Android Apps with Kotlin Course

Overview

App Architecture-Presistence

This is the Sleep tracker app for lesson 6 of the Udacity: Developing Android Apps with Kotlin Course.

  • How to store data
  • Introduction to room data base
  • Using Data Access Object (DAO)
  • Database queries
  • Coroutines - How to make sure your long running database operations don’t slow down the app for the user by using Kotlin coroutines.
  • Use of safeArgs.

Introduction

In most applications, you have some data that you want to hold onto, even when the user closes and leaves the app.

For example, you might want to store a playlist or an inventory of game items, records of expenses and income, a catalog of constellations, or sleep data over time.

In this lesson we are going to build a sleep quality tracker app and use a database to store the sleep data over time. Ul Controller

This app uses a simplified architecture with a UI controller, ViewModel and LiveData, and a room database.


What is roommate base?

Room is a database library that is part of Android jet pack. Room takes care of many of the chores of setting up and configuring a database. And It makes it possible for your app to interact with a database using ordinary function calls.


Designing Entities

The first thing we need is data, which in Kotlin and Android, we represent in data classes, and we need a way to act on that data and our database, which in Kotlin would be function call.

In Room, we need entities and queries.

Entity

Entity represents object or concept to store in the database. Entity class defines a table, each instance is stored as a table row.

Note: Entity as data class.

Query

Query is a request of data or information from a database table, or a combination of tables, or a request to perform some action on the data. Ex: inserting or deleting data. 

Note: Query as interface.


Ul Controller

We use data classes to define our tables and we use annotations to specify things such as which property represents the primary key. We create interfaces that define how to interact with the database which is by DAO.


How to create Entity

  1. Create the data class with parameters. Example: ID, start time and end time.
  2. Annotate the data class with @Entity, and name the table. @Entity(tableName = "daily_sleep_quality_table")
  3. Identify the primary key by annotating it with @PrimaryKey. @PrimaryKey(autoGenerate = true)
  4. Annotate the remaining properties with @ColumnInfo.
@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)

how to create Data Access Object (DAO)

When using Room DB, we query the database by defining and calling Kotlin functions in our code that map to SQL queries. We define those mappings in a DAO using annotation and Room creates the necessary code for us.

DAO Annotations

  • @Insert
  • @Delete
  • @Update
  • @Query

Steps to create DAO:

  1. Create an interface and annotate it with @Dao.
  2. Add an @Insert function.
  3. Add @Query function

Note: we can return LiveData in room DB. This is one of the amazing features of room. Room makes sure that this live data is updated whenever the database is updated. This means that we only have to get this list once. Attach an observer to it and then if the data changes, the UI will update itself to show the changed data without use having to get the data again. 

This saves time, code complexity and most likely a couple of debugging hours on top.


Creating room database

Now that we finally have an entity and a DAO, we can move forward with the database. We need to create an abstract database holder class annotated with database.

This class has method that either creates an instance of the database, if it doesn’t exist or returns a reference to an existing database.

Steps to creating a room database:

  1. Create a public abstract class that extends Room database.
  2. We annotate the class with database in the arguments, declare the entities for the database and set the version number.
  3. Inside a companion object, we define an abstract method or property that returns database DAO.
  4. We only need one instance of the same Room database for the whole app, so we make the Room database a singleton. Note: We use Room’s database builder to create the database only if it doesn’t exist. Otherwise, we return the existing database.

Note: Meaning of @Volatile annotation - This helps us to make sure the value of Instance is always up to data and the same to all execution threads. The value of a volatile variable will never be cached, and all writes and reads will be done to and from the main memory, it means that changes made by one thread to instance are visible to all other threads immediately. And we don’t get the situation where, two threads each update the same entity in a cache.


Abstract keyword:

Abstract keyword is used to declare abstract classes in Kotlin. And abstract class cannot be instantiated (you cannot create objects of an abstract class). However, you can inherit subclasses from them.


Companion object

Companion object are singleton objects whose properties and functions are tied to a class but not the the instance of that class.


Adding ViewModel

https://classroom.udacity.com/courses/ud9012/lessons/fcd3f9aa-3632-4713-a299-ea39939d6fd7/concepts/15877d76-9040-40d6-8978-a8209fa6f627


Multithreading and Coroutines

https://classroom.udacity.com/courses/ud9012/lessons/fcd3f9aa-3632-4713-a299-ea39939d6fd7/concepts/f8c76b29-9f8e-4402-9ff9-d1ec4e3f9312

Multithreading
Getting data from the database might take a long time if there are a lot of data. This long running operation should run on a operate thread.


The operating system can enable an application to create more than one tread of execution within a process. This is called multithreading.

On android, the main thread is a single thread that handles all updates on the UI. The main thread is also the thread that calls all click handlers and other UI and life cycle callbacks. This is why it’s also called the UI thread. The UI thread is the default thread, meaning unless you explicitly switched threads or use a class that runs on a different thread, everything you do is on the main thread.

We should never perform long-running operations on the main or UI thread. Because calling code like this from the main thread can cause the app to pause, stutter or even freeze. If the main thread is blocked for too long, the app may even crash and present an application not responding dialogue.

Coroutines

A pattern for performing long-running tasks without blocking the main thread is callbacks. By using callbacks, you can start long running tasks on a background thread. 

When a task completes, the callback supplied as an argument is called to inform you of the result on the main thread.

In Kotlin, we have coroutines to handle long-running tasks elegantly and efficiently. Kotlin coroutines let you convert callback-based code to sequential code. Code written sequentially is typically easier to read and can even use language features such as exceptions.

In the end, coroutines and call back do exactly the same thing, wait until a result is available from a long-running task and continue execution.

Characteristics of Coroutines:

  • They are asynchronous
  • Non-blocking
  • And use suspend function to make asynchronous code sequential.

What is asynchronous?

Asynchronous means that a coroutine runs independently from the main execution steps of your program. This could be in parallel, on a separate processor, but could also be that while the rest of the app is, for example, waiting for input.

One of the important aspects of async is that we cannot expect the result is available to us until we explicitly wait for it. For example, let’s say you have a question that requires some research and you ask a colleague to find you the answer, they go off and work on it, which is asynchronously and on a separate thread. Unless you wait for the answer, you can continue to do other work that does not depend on their answer, until they come back and tell you what the answer is.

Non-blocking

Non-blocking means the system is not blocking the main or UI thread. So users will always have the smoothest possible experience, because the UI interaction will always have priority.

Note: Because our coroutine code is compiled from sequential code, we don’t need to specify callbacks. And for coroutines, the compiler will make sure the results of the coroutines are available before continuing or resuming.

suspend keyword

The keyword suspend is Kotlin’s way of marking a function or a function type available to coroutines. When a coroutine calls a function marked for suspend, instead of blocking until that function returns like a normal function call, it suspends execution until the result is ready, then it resumes where it left off with the result. Now, while it’s suspended, waiting for a result, it unlocks the threads that its running on, so other functions or coroutines can run.

Blocked thread

So the difference between blocking and suspending is that if a thread is blocked, no other work happens, if the thread is suspended, other work happens until the result is available.

Be aware that the suspend keyword does not specify this thread code runs on. Suspend functions may run on a background thread or a main thread.

Coroutines need…

  • A job - A job is anything that can be canceled. Jobs can be arranged into parent-child hierarchies so that cancellation of a parent leads to an immediate cancellation of all its children, which is a lot more convenient that if we had to do this manually for each coroutine. 

  • A dispatcher - the dispatcher sends off coroutines to run on various threads. For example, dispatcher.main will run task on the main thread, and dispatcher.IO is for offloading blocking IO tasks to a shared pool of threads. 

  • A scope - the scope combines information, including a job and dispatcher, to define the context in which the coroutine runs. Scopes, keep track of coroutines. When you launch a coroutine, it’s in scope, which means that you’ve said which scope will keep track of the coroutine.

Coroutines for Long-running Operations

https://classroom.udacity.com/courses/ud9012/lessons/fcd3f9aa-3632-4713-a299-ea39939d6fd7/concepts/7e5d7478-eca3-466c-bc1b-7997dcab696d

For more information look at the comment section of SleepTrackerViewModel.kt to learn about coroutines.


Recap

  • How to use Room database
  • Created SleepNight data class
  • Created Data Access Object
  • Room database singleton
  • ViewModelFactory for dependency injection
  • ViewModels
  • Coroutines
  • Observable state variables.
You might also like...
Open source Crypto Currency Tracker Android App made fully in Kotlin
Open source Crypto Currency Tracker Android App made fully in Kotlin

CoinBit CoinBit is a beautiful CryptoCurrency app, completely open sourced and 100% in kotlin. It supports following features Track prices of over 300

Episodie is a TV show time tracker app with unusual design written in kotlin and clean architecture approach. Get to know how much time you spent watching tv shows.
Episodie is a TV show time tracker app with unusual design written in kotlin and clean architecture approach. Get to know how much time you spent watching tv shows.

Episodie Episodie is a TV show time tracker app with unusual design. Get to know how much time you spent watching tv shows. Track easily overall progr

Prework for CodePath Android Development Course
Prework for CodePath Android Development Course

Project 1 - Simple ToDo Simple ToDo is an android app that allows building a tod

Dicoding "Belajar Pengembangan Aplikasi Android Intermediate" course submissions

Dicoding: Android Intermediate Submission 📱 This is a repository that contains the source code of my submissions project at Dicoding "Belajar Pengemb

A Simple Expense Tracker App 📱 built to demonstrate the use of modern android architecture component with MVVM Architecture
A Simple Expense Tracker App 📱 built to demonstrate the use of modern android architecture component with MVVM Architecture

Expenso 📊 A Simple Expense Tracker App 📱 built to demonstrate the use of modern android architecture component with MVVM Architecture 🏗 . Made with

Sebuah Aplikasi Elearn dari course Codepolitan

Outline Belajar Ngoding Membuat Tampilan Persiapan Proyek Membuat Halaman Splash Membuat Halaman Login Membuat Halaman Register Membuat Halaman Lupa S

Project for academic course "Telemedicine systems" held on Warsaw University of Technology.

Electronic-Fever-Cards Project for academic course "Telemedicine systems" held on Warsaw University of Technology. This application has two user profi

Mobile Course Assignment 5
Mobile Course Assignment 5

Assignment5 Mobile Course Assignment 5 Widgets that I Use TextView Button Circular Image View Libraries that I use Jetpack Navigation Circular ImageVi

Loop Habit Tracker, a mobile app for creating and maintaining long-term positive habits

Loop is a mobile app that helps you create and maintain good habits, allowing you to achieve your long-term goals. Detailed graphs and statistics show you how your habits improved over time.

Owner
null
AboutMe - From Udacity course Developing Android Apps with Kotlin

AboutMe App From Udacity course "Developing Android Apps with Kotlin".

Anas Tariq 1 Feb 11, 2022
Room : Sleep Quality Tracker app

Room - SleepQualityTracker app This is the toy app for Lesson 6 of the Android App Development in Kotlin course on Udacity. SleepQualityTracker The Sl

Martin 0 Dec 8, 2021
Vaibhav Jaiswal 57 Jan 3, 2023
The SleepQualityTracker app - a demo app that helps you collect information about your sleep

The SleepQualityTracker app is a demo app that helps you collect information about your sleep. This app builds on the SleepQualityTracker previous made, refactoring the code to make it more efficient so it will be easier to maintain and test

Alexandre Pedro 1 Apr 1, 2022
SleepNow - Sleep time recommendation application

Project: SleepNow 슬립 나우 개인 프로젝트 2020.01 ~ 2020.01 0. Overview 슬립나우는 자러 갈 시간이나 일어

Jaemin Yoo 1 May 15, 2022
Asteroid radar app -Second Project from Udacity Advanced Android Development Kotlin Nanodegree

Asteroid radar app Using open-source Nasa Api Asteroid Radar is an app to view the asteroids detected by NASA that pass near Earth, you can view all t

Mostafa Mohamed 2 Aug 29, 2022
A work-in-progress quiz app I started developing for a client but got paused.

quiz-app A work-in-progress quiz app I started developing for a client but got paused. Background This app was intended to be a trivia app where users

Ahmet Safa Orhan 7 Oct 18, 2022
Udacity Nanodegree Project 3

LoadApp In this project students will create an app to download a file from Internet by clicking on a custom-built button where: width of the button g

Kevin Kane 0 Oct 14, 2021
Udacity-shoestore - A template provided for use when building your README file for students

README Template Below is a template provided for use when building your README f

Burak Demir 0 Jan 5, 2022
Water tracker app helps you with daily reminder to drink water. This app is just a trial to test and improve my android development skills.

?? About Me I am a self-thaught developer learning web and android development. This app is just a trial to test and improve my android development sk

Sinan Sonmez (Chaush) 28 Dec 17, 2022