Saving data in a local Android database
Because we develop bespoke Android apps for UK businesses who, a lot of the time, have users (e.g. surveyors, technicians, engineers, drivers, etc.) that have to work in remote areas or perhaps basements with poor or no internet / WiFi connectivity, we need to make sure that any data from remote servers (e.g. job/site data from project management systems and CRMs) persists locally on the app when they don't have an internet connection so the user can still browse that content while they are offline. Any user-initiated content changes are then synced to the server after the device is back online. This is done by saving data to a SQLite database.
What is a SQLite database?
SQLite is a self-contained, serverless, transactional SQL database engine and is the most widely deployed database in the world. It is available on the Android operating system via the android.database.sqlite package.
Unlike most other SQL databases (e.g. Microsoft SQL Server), SQLite does not have a separate server process because it reads and writes directly to disk files (a complete SQL database is contained within a single disk file).
Whilst SQLite runs faster the more memory you give it, performance is usually very good even in low-memory environments such as smartphones and tablets and SQLite responds well to memory failures and disk errors as transactions are ACID even if interrupted by system crashes. In computer science, ACID (Atomicity, Consistency, Isolation, Durability) is a set of database transaction properties meant to guarantee data validity even in the event of errors.
Since we started developing bespoke Android apps for our clients way back in 2009 (doesn't a decade fly by) we have always used Android's SQLite APIs and used an SQL helper to define how our databases look and coded methods that created and maintained the databases and their respective tables. This process can be time consuming and error prone, especially when having to make database table changes when say adding new features to an app we previously developed. Having to update the affected SQL queries manually as well as having to write a lot of boilerplate code to convert between SQL queries and data objects can take a lot of development time and testing.
What is Room?
The Android Team at Google have recently launched a package called "Room" as part of their Architecture Components artifacts.
Room is a database layer that sits on top of the Android app's SQLite database and it deals with the time-consuming tasks that we used to handle with the SQLiteOpenHelper class (a helper class to manage database creation and version management).
Architecture Components help us to structure our bespoke Android apps in a way that is robust, testable, and maintainable with less boilerplate code. The less we have to code, the less we have to charge!
Room offers a layer that sits over SQLite to allow easy database access whilst maintaining the full power of SQLite.
There are 3 major components in Room:
Database: the main access point for app's persisted, relational data.
Entity: Represents a table within the database and to persist data we will use the Room persistence library where our bespoke Android app developers can define sets of related fields as "entities". A database table is created for each entity. However, to persist a field, Room must be given access to it, so we must either make it a public field or we can code a getter and setter (using JavaBean-like conventions in Room).
DAO (data access object): Contains the methods used for accessing the database. By accessing the bespoke Android app's database using a DAO class, instead of say the old-school method of query builders or using direct queries, we can separate different components of the app's database architecture which also permits us to simulate database access when we test your app. Also, these database queries run asynchronously on a background thread so we don't risk locking the user interface (UI) when retrieving lots of data (i.e. the screen freezing).
Our app can use the Room database to get the data access objects which in turn get entities from the database and save any changes to those entities back to the database. The app uses an entity to save and retrieve values that correspond to table columns within the database.
What is a Repository?
A Repository is a class that we can use to access many different data sources (it handles data operations). Whilst the Repository is not part of the Android "Architecture Components" libraries, it is recommended as best practice for professional Android app developers such as us in order to allow for the separation of code and architecture. This gives us a clean API which we can use throughout the bespoke Android app we develop for you in order to get data (here we implement the logic for deciding whether to fetch data from a cloud server or use results cached in a local database).
What is a ViewModel?
The ViewModel is part of the Android lifecycle library and its role is to provide data to the UI and survive any configuration changes (e.g. if the user rotates the phone from portrait to landscape). A ViewModel manages communication between the Repository and the UI. We can also use a ViewModel to share data between fragments. Basically, activities and fragments draw data to the screen and the ViewModel looks after the data needed for the UI (e.g. data needed to populate a list seen on the Android app screen).