Professional Documents
Culture Documents
Textbook Android S Architecture Components Version 0 10 Mark L Murphy Ebook All Chapter PDF
Textbook Android S Architecture Components Version 0 10 Mark L Murphy Ebook All Chapter PDF
https://textbookfull.com/product/elements-of-android-jetpack-
version-1-1-mark-l-murphy/
https://textbookfull.com/product/the-busy-coder-s-guide-to-
android-development-8-1-mark-l-murphy/
https://textbookfull.com/product/elements-of-kotlin-mark-l-
murphy/
https://textbookfull.com/product/android-studio-3-0-development-
essentials-android-8-edition-neil-smyth/
The Hitchhiker s Guide to Online Anonymity Version 0 9
4 May 2021 Anonymousplanet
https://textbookfull.com/product/the-hitchhiker-s-guide-to-
online-anonymity-version-0-9-4-may-2021-anonymousplanet/
https://textbookfull.com/product/postgresql-up-running-3rd-
edition-covers-version-10-regina-o-obe-leo-s-hsu/
https://textbookfull.com/product/information-systems-a-manager-s-
guide-to-harnessing-technology-version-8-0-8th-edition-john-
gallaugher/
https://textbookfull.com/product/android-software-internals-
quick-reference-a-field-manual-and-security-reference-guide-to-
java-based-android-components-1st-edition-james-stevenson/
https://textbookfull.com/product/free-pascal-reference-guide-
version-3-0-2-michael-van-canneyt/
Android’s Architecture Components
by Mark L. Murphy
Android’s Architecture Components
by Mark L. Murphy
Printing History:
July 2018: Version 0.10
The CommonsWare name and logo, “Busy Coder's Guide”, and related trade dress are trademarks of CommonsWare,
LLC.
All other trademarks referenced in this book are trademarks of their respective frms.
The publisher and author(s) assume no responsibility for errors or omissions or for damages resulting from the use of the
information contained herein.
Table of Contents
Headings formatted in bold-italic have changed since the last version.
• Preface
◦ How the Book Is Structured ............................................................... vii
◦ Prerequisites ....................................................................................... viii
◦ About the Updates ............................................................................. viii
◦ What’s New in Version 0.10? .................................................... viii
◦ Warescription ....................................................................................... ix
◦ Book Bug Bounty ................................................................................... x
◦ Source Code and Its License ................................................................. x
◦ Creative Commons and the Four-to-Free (42F) Guarantee ....... xi
◦ Acknowledgments ................................................................................ xi
• Room Basics
◦ Wrenching Relations Into Objects ....................................................... 1
◦ Room Requirements ................................................................... 2
◦ Room Furnishings .................................................................................. 3
◦ Get a Room ............................................................................................ 9
• Testing Room
◦ Writing Instrumentation Tests ............................................................ 11
◦ Writing Unit Tests via Mocks .............................................................. 15
• The Dao of Entities
◦ Configuring Entities ............................................................................ 21
◦ DAOs and Queries ................................................................................ 31
◦ Dynamic Queries ................................................................................. 37
◦ Other DAO Operations ....................................................................... 39
◦ Transactions and Room ....................................................................... 42
◦ Threads and Room ............................................................................. 44
• Room and Custom Types
◦ Type Converters ................................................................................... 45
◦ Embedded Types .................................................................................. 53
◦ Updating the Trip Sample ................................................................... 56
• Room and Relations
◦ The Classic ORM Approach ................................................................ 61
◦ A History of Threading Mistakes ........................................................ 62
◦ The Room Approach ........................................................................... 63
◦ Plans for Trips ..................................................................................... 64
◦ Self-Referential Relations for Tree Structures ................................... 72
i
◦ Using @Relation .................................................................................. 74
◦ @Relation and @Query ....................................................................... 76
◦ Representing No Relation ................................................................... 76
• The Support Database API
◦ “Can’t You See That This is a Facade?” ............................................... 79
◦ When Will We Use This? .................................................................... 81
◦ Configuring Room’s Database Access ................................................. 81
◦ Consuming the Support Database API Directly ............................... 84
• Room and Migrations
◦ What’s a Migration? ............................................................................ 91
◦ When Do We Migrate? ........................................................................ 92
◦ But First, a Word About Exporting Schemas ..................................... 92
◦ Writing Migrations .............................................................................. 95
◦ Employing Migrations ....................................................................... 100
◦ How Room Applies Migrations ......................................................... 102
◦ Testing Migrations .................................................................. 102
◦ Migrating Under Protest ................................................................... 107
• Securing Your Room
◦ Meet the Players ................................................................................ 109
◦ Using CWAC-SafeRoom ..................................................................... 110
◦ More to Come! .................................................................................... 112
• Lifecycles and Owners
◦ A Tale of Terminology ........................................................................ 115
◦ Adding the Lifecycle Components ........................................... 116
◦ Getting a Lifecycle .............................................................................. 117
◦ Observing a Lifecycle ......................................................................... 119
◦ Legacy Options ........................................................................ 120
◦ So, What’s the Point of This? ............................................................ 124
• LiveData
◦ Observables Are the New Black ........................................................ 125
◦ Yet More Terminology ....................................................................... 126
◦ Implementing LiveData .......................................................... 127
◦ Other LiveData Examples .................................................................. 133
◦ Testing LiveData ................................................................................. 135
• ViewModel
◦ ViewModels, As Originally Envisioned ............................................. 137
◦ ViewModel Versus… .......................................................................... 138
◦ Dependencies ..................................................................................... 139
◦ Mommy, Where Do ViewModels Come From? ............................... 139
◦ ViewModels, Google’s Way ............................................................... 140
◦ ViewModels as Simple POJOs ........................................................... 143
ii
◦ ViewModels and Scopes ........................................................... 146
• Other Lifecycle Owners
◦ ProcessLifecycleOwner ...................................................................... 161
◦ LifecycleService .................................................................................. 165
◦ Wait… Where Are LifecycleProvider and LifecycleReceiver? ... 165
• LiveData and Data Binding
◦ A Data Binding Recap .............................................................. 167
◦ LiveData Updating Data Binding ............................................ 170
◦ Handling Changes to LiveData ............................................... 176
◦ The Saved Instance State Situation .................................................. 178
• WorkManager
◦ Where Should We Use WorkManager? .................................... 183
◦ Where Should We Not Use WorkManager? .............................. 184
◦ WorkManager Dependencies .................................................. 184
◦ Workers: They Do Work ........................................................... 185
◦ Performing Simple Work ......................................................... 187
◦ Work Inputs ............................................................................. 187
◦ Constrained Work .................................................................... 188
◦ Tagged Work ............................................................................ 189
◦ Monitoring Work .................................................................... 190
◦ Canceling Work ........................................................................ 194
◦ Delayed Work ........................................................................... 195
◦ Parallel Work ........................................................................... 195
◦ Chained Work .......................................................................... 196
◦ Periodic Work ......................................................................... 202
◦ Unique Work ........................................................................... 202
◦ Testing Work ........................................................................... 203
• M:N Relations in Room
◦ Implementing a Join Entity .............................................................. 209
◦ Implementing DAO Methods ............................................................ 213
◦ Where’s That Good Ol’ Object Feel? ................................................. 215
• Polymorphic Room Relations
◦ Polymorphism With Separate Tables ................................................ 217
◦ Polymorphism With a Single Table .................................................. 222
◦ Polymorphism With M:N Relations ................................................. 226
• LiveData Transformations
◦ The Bucket Brigade ........................................................................... 227
◦ Mapping Data to Data ....................................................................... 228
◦ Mapping Data to… LiveData? ............................................................ 230
◦ Writing a Transformation ...................................................... 230
◦ Do We Really Want This? ................................................................. 232
iii
• RxJava and Room
◦ Adding RxJava .......................................................................... 235
◦ A Quick Sidebar on Rx Testing ......................................................... 236
◦ Rx Query Response Types ................................................................. 237
◦ Applying This to Your UI .................................................................. 242
◦ @RawQuery and Reactive Responses ............................................... 243
• RxJava and Lifecycles
◦ The Classic Approach ........................................................................ 245
◦ Bridging RxJava and LiveData ............................................... 246
◦ The Uber Solution: AutoDispose ...................................................... 249
◦ The Semi-Deprecated Solution: RxLifecycle ................................... 249
• Packing Up a Room
◦ The Problem ........................................................................................ 251
◦ The Classic Solution: SQLiteAssetHelper ........................................ 252
◦ The New Problem .............................................................................. 253
◦ Merging SQLiteAssetHelper with Room .......................................... 253
• Paging Room Data
◦ The Problem: Too Much Data ........................................................... 257
◦ Addressing the UX ............................................................................. 258
◦ Enter the Paging Library ................................................................... 258
◦ Paging and Room .................................................................... 260
◦ What About RxJava? ......................................................................... 269
• Immutability
◦ The Benefits of Immutability ............................................................ 273
◦ The Costs of Immutability ................................................................ 275
◦ Immutability via AutoValue ................................................... 278
• The Repository Pattern
◦ What the Repository Does ................................................................ 283
◦ High-Level Repository Strategies .................................................... 286
◦ Let’s Roll the Dice ............................................................................. 288
◦ Blending Data Sources ...................................................................... 301
• Introducing Model-View-Intent
◦ GUI Architectures ............................................................................... 311
◦ Why People Worry About GUI Architectures .................................. 312
◦ Why Others Ignore GUI Architectures ............................................ 314
◦ A Rough Comparison of GUI Architectures .................................... 316
◦ The Basics of Model-View-Intent ..................................................... 319
◦ Additional MVI Resources ................................................................ 323
• A Deep Dive Into MVI
◦ What the Sample App Does .............................................................. 325
◦ MVI and the Sample App .................................................................. 333
iv
◦ The Model .......................................................................................... 334
◦ The View State ................................................................................... 336
◦ The View ............................................................................................ 338
◦ The Actions ........................................................................................ 342
◦ Publishing Actions .................................................................. 346
◦ The Repositories ................................................................................ 348
◦ The Controller .................................................................................... 353
◦ About Those Results .......................................................................... 357
◦ The Reducer in the RosterViewModel ............................................. 359
◦ Examining the Other Fragments ...................................................... 364
◦ Summary ............................................................................................ 365
• Backing Up a Room
◦ What Do We Need to Back Up? ............................................... 369
◦ Beware of Open Rooms ............................................................ 371
◦ When Do We Back Up the Database? ...................................... 371
◦ A Basic Backup Example .......................................................... 373
◦ Backing Up Off-Device ............................................................ 380
• Room and Full-Text Searching
◦ What Is FTS? ...................................................................................... 381
◦ What You Can’t Do ............................................................................ 382
◦ The FTS Recipe .................................................................................. 382
◦ Searching a Book ............................................................................... 384
• Configuring SQLite Beyond Room
◦ When To Make Changes ................................................................... 405
◦ Example: Turbo Boost Mode ............................................................ 406
v
Preface
Thanks!
Thanks for your interest in Android app development, the world’s most popular
operating system! And, thanks for your interest in the Android Architecture
Components, released by Google in 2017 to help address common “big-ticket”
problems in Android app development.
And, most of all, thanks for your interest in this book! I sincerely hope you find it
useful!
(OTOH, if you find it completely useless… um, don’t tell anyone, OK?)
We then move into the lifecycle components. These components help you deal with
objects that have lifecycles, particularly activities and services. The LiveData class in
particular gives you a lightweight “reactive” way of consuming data while still
honoring things like configuration changes and the typical activity/fragment
destroy-and-recreate cycle. We will also peek at ViewModel, the Architecture
Components’ way of helping you maintain state across configuration changes. We
will see how other libraries, like data binding and RxJava, can be tied into the
Architecture Components.
vii
PREFACE
repository pattern and major GUI architecture patterns. Then, we start to investigate
one of those GUI architectures — Model-View-Intent (MVI) — in detail, through
some larger sample apps.
Prerequisites
This book is targeted at:
• People who have read the core chapters of the companion volume, The Busy
Coder’s Guide to Android Development, or
• Intermediate Android app developers — those with some experience but not
necessarily “experts” in the field
If you obtained this book through the Warescription, you will be able to download
updates as they become available, for the duration of your subscription period.
If you obtained this book through other channels… um, well, it’s still a really nice
book!
Each release has notations to show what is new or changed compared with the
immediately preceding release:
And, there is the “What’s New” section, just below this paragraph.
viii
PREFACE
Warescription
If you purchased the Warescription, read on! If you obtained this book from other
channels, feel free to jump ahead.
The Warescription entitles you, for the duration of your subscription, to digital
editions of this book and its updates, in PDF, EPUB, and Kindle (MOBI/KF8)
formats. You also have access to other titles that CommonsWare publishes during
that subscription period, such as the aforementioned The Busy Coder’s Guide to
Android Development.
Each subscriber gets personalized editions of all editions of each title. That way,
your books are never out of date for long, and you can take advantage of new
material as it is made available.
However, you can only download the books while you have an active Warescription.
There is a grace period after your Warescription ends: you can still download the
book until the next book update comes out after your Warescription ends. After
that, you can no longer download the book. Hence, please download your
updates as they come out. You can find out when new releases of this book are
available via:
1. The CommonsBlog
2. The CommonsWare Twitter feed
3. The Warescription newsletter, which you can subscribe to off of your
Warescription page
4. Just check back on the Warescription site every month or two
• “Office hours” — online chats to help you get answers to your Android
application development questions. You will find a calendar for these on
your Warescription page.
• A Stack Overflow “bump” service, to get additional attention for a question
that you have posted there that does not have an adequate answer.
• A discussion board for asking arbitrary questions about Android app
ix
PREFACE
development
Be the first to report a unique concrete problem in the current digital edition, and
CommonsWare will extend your Warescription by six months as a bounty for
helping CommonsWare deliver a better product.
1. Typographical errors
2. Sample applications that do not work as advertised, in the environment
described in the book
3. Factual errors that cannot be open to interpretation
By “unique”, we mean ones not yet reported. Be sure to check the book’s errata page,
though, to see if your issue has already been reported. One coupon is given per
email containing valid bug reports.
1. Places where you think we are in error, but where we feel our interpretation
is reasonable
2. Places where you think we could add sample applications, or expand upon
the existing material
3. Samples that do not work due to “shifting sands” of the underlying
environment (e.g., changed APIs with new releases of an SDK)
However, those “softer” issues do not qualify for the formal bounty program.
Questions about the bug bounty, or problems you wish to report for bounty
consideration, should be sent to bounty@commonsware.com.
x
PREFACE
Copying source code directly from the book, in the PDF editions, works best with
Adobe Reader, though it may also work with other PDF viewers. Some PDF viewers,
for reasons that remain unclear, foul up copying the source code to the clipboard
when it is selected.
This edition of this book will be available under the aforementioned Creative
Commons license on 1 July 2022. Of course, watch the CommonsWare Web site, as
this edition might be relicensed sooner based on sales.
Note that future editions of this book will become free on later dates, each four years
from the publication of that edition or based on sales of that specific edition.
Releasing one edition under the Creative Commons license does not automatically
release all editions under that license.
Acknowledgments
The author would like to thank the Google team responsible for the Architecture
Components for their work in making this library.
xi
Room
Room Basics
Google describes Room as providing “an abstraction layer over SQLite to allow fluent
database access while harnessing the full power of SQLite.”
In other words, Room aims to make your use of SQLite easier, through a lightweight
annotation-based implementation of an object-relational mapping (ORM) engine.
NOTE: The material in this chapter — and in all the chapters of this book edition —
is based on the 1.0.0 release of Room. Since this is a preview release, there may be
changes in newer versions that affect you.
1
ROOM BASICS
and ContentValues are objects, they are fairly generic, much in the way that a
HashMap or ArrayList is generic. In particular, neither Cursor nor ContentValues
has any of our business logic. We have to somehow either wrap that around those
objects or convert between those objects and some of ours.
The quintessential Java ORM is Hibernate. However, Hibernate was developed with
server-side Java in mind and is not well-suited for slim platfoms like Android
devices. However, a vast roster of Android ORMs have been created over the years to
try to fill that gap. Some of the more popular ones have been:
• DBFlow
• greenDAO
• OrmLite
• Sugar ORM
Room also helps with the object-relational impedance mismatch. It is not as deep of
an ORM as some of the others, as you will be dealing with SQL a fair bit. However,
Room has one huge advantage: it is from Google, and therefore it will be deemed
“official” in the eyes of many developers and middle managers.
While this book is focused on the Architecture Components — and Room is part of
those — you may wish to explore other ORMs if you are interested in using Java
objects but saving the data in SQLite. Room is likely to become popular, but it is far
from the only option.
Room Requirements
To use Room, you need two dependencies in your module’s build.gradle file:
implementation "android.arch.persistence.room:runtime:1.1.1"
annotationProcessor "android.arch.persistence.room:compiler:1.1.1"
2
ROOM BASICS
(from Trips/RoomBasics/app/build.gradle)
Note that Room has a minSdkVersion requirement of API Level 15 or higher. If you
attempt to build with a lower minSdkVersion, you will get a build error. If you try to
override Room’s minSdkVersion using manifest merger elements, while the project
will build, expect Room to crash horribly.
Room Furnishings
Roughly speaking, your use of Room is divided into three sets of classes:
1. Entities, which are POJOs that model the data you are transferring into and
out of the database
2. The data access object (DAO), that provides the description of the Java API
that you want for working with certain entities
3. The database, which ties together all of the entities and DAOs for a single
SQLite database
If you have used Square’s Retrofit, some of this will seem familiar:
In this chapter, we will look at the Trips/RoomBasics sample project. This app is the
first of a linked series of apps that we will examine in this book, as we build a travel
itinerary manager. It will track your upcoming trips in a database and allow you to
add, edit, and remove trips. Right now, though, we are settling for being able to see
some very rudimentary trips get into and out of a database.
Entities
In many ORM systems, the entity (or that system’s equivalent) is a POJO that you
happen to want to store in the database. It usually represents some part of your
overall domain model, so a payroll system might have entities representing
departments, employees, and paychecks.
With Room, a better description of entities is that they are POJOs representing:
• the data that you want to store into the database, and
3
ROOM BASICS
• a typical unit of a result set that you are trying to retrieve from the database
That difference may sound academic. It starts to come into play a bit more when we
start thinking about relations.
However, it also more closely matches the way Retrofit maps to Web services. With
Retrofit, we are not describing the contents of the Web service’s database. Rather, we
are describing how we want to work with defined Web service endpoints. Those
endpoints have a particular set of content that we can work with, courtesy of
whoever developed the Web service. We are simply mapping those to methods and
POJOs, both for input and output. Room is somewhere in between a Retrofit-style
“we just take what the Web service gives us” approach and a full ORM-style “we
control everything about the database” approach.
Tactically, an entity is a Java class marked with the @Entity annotation. For example,
here is a Trip class that serves as a Room entity:
package com.commonsware.android.room;
import android.arch.persistence.room.Entity
android.arch.persistence.room.Entity;
import android.arch.persistence.room.Ignore
android.arch.persistence.room.Ignore;
import android.arch.persistence.room.PrimaryKey
android.arch.persistence.room.PrimaryKey;
import android.support.annotation.NonNull
android.support.annotation.NonNull;
import java.util.UUID
java.util.UUID;
@Entity(tableName = "trips")
class Trip {
@PrimaryKey
@NonNull
public final String id;
public final String title;
final int duration;
@Ignore
Trip(String title, int duration) {
this
this(UUID.randomUUID().toString(), title, duration);
}
@Override
4
ROOM BASICS
(from Trips/RoomBasics/app/src/main/java/com/commonsware/android/room/Trip.java)
There is no particular superclass required for entities, and the expectation is that
often they will be simple POJOs, as we see here.
Sometimes, your fields will be marked with annotations describing their roles. In
this example, the id field has the @PrimaryKey annotation, telling Room that this is
the unique identifier for this entity. Room will use that to know how to update and
delete Trip objects by their primary key values. Room also requires that any
@PrimaryKey field of an object type — like String – be annotated with @NonNull, as
primary keys in SQLite cannot be null.
Similarly, sometimes your methods will be marked with annotations. In this case,
Trip has two constructors: one that generates the id from a UUID, and one that takes
the id as a constructor parameter. Room needs to know which constructor(s) are
eligible for its use; you mark the other constructors with the @Ignore annotation.
For Room to work with a field, it needs to be public or have JavaBean-style getter
and setter methods, so Room can access them. If the fields are final, as they are on
Trip, Room will try to find a constructor to use to populate the fields, as final fields
will lack setters.
DAO
“Data access object” (or DAO for short) is a fancy way of saying “the API into the
data”. The idea is that you have a DAO that provides methods for the database
operations that you need: queries, inserts, updates, deletes, whatever.
The primary role of the @Dao-annotated abstract class or interface is to have one
or more methods, with their own Room annotations, identifying what you want to
do with the database and your entities. This serves the same role as the methods
5
ROOM BASICS
package com.commonsware.android.room;
import android.arch.persistence.room.Dao
android.arch.persistence.room.Dao;
import android.arch.persistence.room.Delete
android.arch.persistence.room.Delete;
import android.arch.persistence.room.Insert
android.arch.persistence.room.Insert;
import android.arch.persistence.room.OnConflictStrategy
android.arch.persistence.room.OnConflictStrategy;
import android.arch.persistence.room.Query
android.arch.persistence.room.Query;
import android.arch.persistence.room.Update
android.arch.persistence.room.Update;
import java.util.List
java.util.List;
@Dao
interface TripStore {
@Query("SELECT * FROM trips ORDER BY title")
List<Trip> selectAll();
@Insert
void insert(Trip... trips);
@Update
void update(Trip... trips);
@Delete
void delete(Trip... trips);
}
(from Trips/RoomBasics/app/src/main/java/com/commonsware/android/room/TripStore.java)
Besides the @Dao annotation on the TripStore interface, we have five methods, each
with their own annotations. Your four main annotations for these methods are
@Query, @Insert, @Update, and @Delete, which map to the corresponding database
operations.
6
ROOM BASICS
statement wherever we might have used ? to indicate the value to bind in.
The remaining three methods use the @Insert, @Update, and @Delete annotations,
mapped to methods of the same name. Here, the methods take a varargs of Trip,
meaning that we can insert, update, or delete as many Trip objects as we want
(passing in zero Trip objects works, though that would be rather odd).
If you want custom code on your DAO, beyond the code-generated implementations
of your Room-annotated methods, use an abstract class and mark all the Room-
annotated methods as abstract. If, on the other hand, all you need on the DAO are
the Room-annotated methods, you can use an interface and skip all the abstract
keywords, as we did with TripStore.
Database
In addition to entities and DAOs, you will have at least one @Database-annotated
abstract class, extending a RoomDatabase base class. This class knits together the
database file, the entities, and the DAOs.
package com.commonsware.android.room;
import android.arch.persistence.room.Database
android.arch.persistence.room.Database;
import android.arch.persistence.room.Room
android.arch.persistence.room.Room;
import android.arch.persistence.room.RoomDatabase
android.arch.persistence.room.RoomDatabase;
import android.content.Context
android.content.Context;
@Database(entities={Trip.class}, version=1)
abstract class TripDatabase extends RoomDatabase {
abstract TripStore tripStore();
return
return(INSTANCE);
}
7
ROOM BASICS
if (memoryOnly) {
b=Room.inMemoryDatabaseBuilder(ctxt.getApplicationContext(),
TripDatabase.class);
}
else {
b=Room.databaseBuilder(ctxt.getApplicationContext(), TripDatabase.class,
DB_NAME);
}
return
return(b.build());
}
}
(from Trips/RoomBasics/app/src/main/java/com/commonsware/android/room/TripDatabase.java)
• Identifying all of the entity classes that you care about in the entities
collection
• Identifying the schema version of the database (as you see with
SQLiteOpenHelper in conventional Android SQLite development)
@Database(entities={Trip.class}, version=1)
(from Trips/RoomBasics/app/src/main/java/com/commonsware/android/room/TripDatabase.java)
Here, we are saying that we have just one entity class (Trip), and that this is schema
version 1.
You also need abstract methods for each DAO class that return an instance of that
class:
(from Trips/RoomBasics/app/src/main/java/com/commonsware/android/room/TripDatabase.java)
In this app, we have but one DAO (TripStore), so we have an abstract method to
return an instance of TripStore.
8
ROOM BASICS
up to you, and some apps may elect to have nothing more here.
Get a Room
In this example, the database is a singleton. TripDatabase has a static getter
method, cunningly named get(), that creates our singleton. get(), in turn, calls a
create() method that is responsible for creating our TripDatabase:
if (memoryOnly) {
b=Room.inMemoryDatabaseBuilder(ctxt.getApplicationContext(),
TripDatabase.class);
}
else {
b=Room.databaseBuilder(ctxt.getApplicationContext(), TripDatabase.class,
DB_NAME);
}
return
return(b.build());
}
(from Trips/RoomBasics/app/src/main/java/com/commonsware/android/room/TripDatabase.java)
Both of those methods take a Context and the Java Class object for the desired
RoomDatabase subclass. databaseBuilder() also takes the filename of the SQLite
database to use, much as SQLiteOpenHelper does in traditional Android SQLite
development.
While there are some configuration methods that can be called on the
RoomDatabase.Builder, we skip those here, simply calling build() to build the
TripDatabase. The result is that when we call get(), we get a singleton lazy-
9
ROOM BASICS
initialized TripDatabase.
We will see how to do that in the next chapter, where we look at how to write
instrumentation tests for our Room-generated database code.
10
Testing Room
Once you have a RoomDatabase and its associated DAO(s) and entities set up, you
should start testing it.
The good news is that testing Room is not dramatically different than is testing
anything else in Android. Room has a few characteristics that make it a bit easier
than some things to test, as it turns out.
So, for example, here is an instrumentation test case class to exercise the
TripDatabase from the preceding chapter:
package com.commonsware.android.room;
import android.support.test.InstrumentationRegistry
android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4
android.support.test.runner.AndroidJUnit4;
import org.junit.After
org.junit.After;
import org.junit.Before
org.junit.Before;
import org.junit.Test
org.junit.Test;
import org.junit.runner.RunWith
org.junit.runner.RunWith;
import java.util.List
java.util.List;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
11
TESTING ROOM
@RunWith(AndroidJUnit4.class)
public class TripTests {
TripDatabase db;
TripStore store;
@Before
public void setUp() {
db=TripDatabase.create(InstrumentationRegistry.getTargetContext(), true
true);
store=db.tripStore();
}
@After
public void tearDown() {
db.close();
}
@Test
public void basics() {
assertEquals(0, store.selectAll().size());
assertNotNull(first.id);
assertNotEquals(0, first.id.length());
store.insert(first);
assertTrip(store, first);
store.update(updated);
assertTrip(store, updated);
store.delete(updated);
assertEquals(0, store.selectAll().size());
}
assertNotNull(results);
assertEquals(1, results.size());
assertTrue(areIdentical(trip, results.get(0)));
Trip result=store.findById(trip.id);
assertNotNull(result);
assertTrue(areIdentical(trip, result));
12
Another random document with
no related content on Scribd:
adolescente della casa Imperiosa. Colla chioma biondissima e l’alba
pelle e l’occhio tinto di cielo e lucentissimo per la gagliarda
fosforescenza del cervello, sembrava accennasse alle Gallie, alla
Bretagna, alla Germania, e invitasse a non ancor noti connubii la
cæruleam pubem.
«Ma la damiatrice pronunciò la preghiera, maritandola ad una
antichissima cantilena del Lazio:
«Castissima dea, che le assidue ripulse al Fauno procace, a te,
ancora terrestre, costaron sangue innocente; onde l’Olimpo ti
accolse pietoso nella propria luce, inspira e consiglia e sgomenta il
senso delle mortali che qui ti adorano. Rinnovella le virtù prische
della neonata Roma, e dalla muliebre purezza sia redento e salvo e
fatto glorioso e invitto il popolo romano.»
«Queste ultime parole, affidate alla stessa cantilena, vennero
ripetute in coro da quante donne erano là inginocchiate, alcune delle
quali si ribellavano all’alto concetto della preghiera.
«Quando tacquero i canti, la damiatrice s’accinse a compiere il
sagrificio che chiamavasi Damium, da Damia, altro nome che teneva
la dea, donde venne l’appellativo alla sagrificatrice. Questa immolò
alcune galline di varii colori, tranne il nero; dopo di che, dodici tra le
più giovani vestali, immersero nel Mellario altrettante coppe d’oro, e
così colme le recarono in giro. Tutte le donne ne bevettero, e le
vergini ivano e redivano colle coppe ognora vuotate e ognora
ricolme, continuando in tale servizio, finchè il Mellario rimase
esausto. Allora la sagrificatrice esclamò ad alta voce e in lingua
greca. Evviva il frutto di Bacco — e tosto cominciarono le danze
bacchiche, e alquante donne, tra le più giovani e formose, e indarno
devote alla moglie del Fauno, travestitesi in Menadi e Tiadi e
Bassaree, le seguaci assidue di Bacco, si sciolsero le chiome,
svestirono le stole e i pepli prolissi e apparvero in pelli succinte,
scuotendo cimbali e tirsi e spade serpentine. Forse è perciò che agli
uomini era interdetta quella solennità sacra, perchè i fumi vinosi
esaltando nella danza vorticosa talune di quelle che eran sazie della
settimana oziata, le eccitavano ad imitare le ignude baccanti,
fors’anche per rivelare alle invide amiche le nascose bellezze» [162].
Ignorasi ciò che veramente accadesse in questi misteri della Bona
Dea. Clodio v’andò in tutti i modi sospinto da soli intenti di lussuria, e
come che scoperto, si vociasse per Roma, che a tanto avesse
trascorso per amor di Pompea, figliuola del magno Pompeo e moglie
di Cesare, questi, sebbene nell’orgoglio suo diniegasse la cosa, pur
l’addusse a causa di divorzio, con quelle parole, delle quali pur a’ dì
nostri si usò tanto ed abusò, che la moglie di Cesare non debba
tampoco venir sospettata, adoperandosi per altro alla assoluzione
del dissoluto profanatore dei sacri misteri.
Nell’epoca imperiale, il velame di questi si squarciò, e quali
cerimonie si compissero non fu più uomo che ignorasse. Giovenale,
l’implacabile poeta satirico, così li rese noti alla posterità:
Lo stesso caustico poeta più giù nella stessa satira constata che
l’esempio di Clodio trovò imitatori di poi, nè i misteri della Bona Dea
soltanto venissero profanati, ma quelli pure d’altri numi ed ogni
altare:
La memoria della festa della Buona Dea dovevasi per tali ragioni e
invereconde costumanze nel presente capitolo dell’opera mia
menzionare e molto più ancora perchè si sappia che certamente
degenerasse sempre più col tempo in licenza ed in abbominazioni;
tanto così che il medesimo Giovenale, parlando dei sacerdoti di
essa, li avesse a paragonare a quelli di Cotitto, che si celebravano
egualmente di nottetempo in Grecia fra le più sconce dissolutezze,
onde i Bapti, che così nomavansi i suoi ministri, fossero venuti nel
generale disprezzo de’ concittadini, ed Alcibiade che s’era fatto
iniziare a’ loro misteri, avesse ad uccidere il poeta comico Eupoli,
che di ciò l’aveva canzonato in una sua commedia.
In quel luogo Giovenale accenna che i misteri della Buona Dea si
fossero anzi fin da’ suoi giorni così sconvolti, che non più alle donne,
ma agli uomini si aprissero solamente.
Accipient te
Paulatim, qui longa domi redimicula sumunt
Frontibus, et toto posuere monilia collo,
Atque Bonam teneris placant abdomine porcæ,
Et magno cratere Deam. Sed more sinistro
Exagitata procul non intrat fœmina limen.
Solis ara Dea maribus patet. Ite, profanæ!
Clamatur: nullo gemit hic tibicine cornu.
Talia secreta coluerunt orgia tæda
Cecropiam soliti Baptæ lassare Cotytto [165].
Dissi finalmente, nel cominciar a parlare della festa della Buona Dea,
non già perchè fosse ultimata la storia della prostituzione sacra in
Roma, ma perchè si assomigliassero poi tutti gli altri molti
abbominevoli culti che le più abbiette passioni avevano potuto
immaginare, ed ai quali piegavano anche quelle matrone romane
che pur affettavano schifiltose di non volersi mescere alle orgie di
Venere. Cupido, a cagion d’esempio, aveva i suoi riti; li aveva Mutino
e Pertunda, Persica e Prema, Volupia e Lubenzia, Tulana e Ticone,
ed altri infiniti quanti erano i modi di estrinsecar la lascivia, tutti
oscenissimi iddii che si facevano presiedere ad uffici che il pudore
vieta di qui spiegare.
Alla prostituzione religiosa, tenne dietro ben presto la legale, per
l’affluenza a Roma delle donne forestiere in cerca di fortuna e
massime delle auletridi greche condotte schiave; ma le donne che vi
si dedicavano erano notate d’infamia. Imperocchè le leggi
cercassero sempre di proteggere il costume, tal che le adultere
venissero ne’ primi tempi ad essere condotte all’asino, e dopo
essere state vittima di questo animale, andassero abbandonate al
popolaccio. Ho nel capitolo della Basilica, parlando delle pene
dell’adulterio, fatto cenno di quelle specialmente in vigore in Pompei,
d’una specie di gogna, cioè, che all’adultera si infliggeva
costringendola a percorrere le vie della città a cavalcion d’un asino
col dorso volto alla testa e rimanendo così perpetuamente notate di
indelebile vitupero. Ma il marchio d’infamia non impedì che ne’ tempi
del basso impero femmine libere e di nobile schiatta, si dedicassero
alla prostituzione, conseguendo dagli edili il brevetto relativo, che si
chiamava licentia stupri, il qual consisteva nel farsi iscrivere nei ruoli
meretricii col nome di nascita e con quello che adottavano
nell’infame commercio, e che dicevasi nomen lupanarium e tale
iscrizione che le assoggettava alla vigilanza dell’edile, implicava tal
nota indelebile di infamia, che anco il ritorno alla vita onesta, il
matrimonio, o qualunque potere non avevan forza di riabilitarle
interamente o di farne cancellare il nome dal libro infame.
Il dichiararsi cortigiana e farsi iscrivere tale nei registri dell’edilità
sottraeva l’adultera alle severe pene dell’adulterio, e sotto l’impero
— incredibile a dirsi — furon viste figlie e mogli di senatori
inscrivervisi sfrontatamente. Le matrone poi per abbandonarsi alla
vita dissoluta e sottrarsi al rigore delle leggi, vestivansi da schiave e
prostitute, esponendosi a que’ publici oltraggi cui le schiave e le
prostitute non avevano dritto a reclamo. Si sa di Messalina moglie di
Claudio imperatore, per l’episodio che di sfuggita accennai più
sopra, narrato da Giovenale, ch’essa, togliendosi al talamo
imperiale, sotto le vesti ed il nome di Licisca, si offerisse nel più
lurido lupanare di Roma agli abbracciamenti di schiavi e mulattieri, e
così spinse la impudenza nella libidine, che durante un viaggio
dell’imbecille marito, immaginò di contrarre publicamente un
secondo imeneo con Silio, lo che peraltro costò a quest’ultimo la
testa. Nè più savia fu l’altra moglie di Claudio, Urgalanilla; nè migliori
erano state quelle altre impudiche imperiali, che furono Giulia,
Scribonia e Livia; nè la Ippia, moglie del senatore Vejentone, che
abbandonando marito e figli seguì delirante Sergio, il guercio
gladiatore, comunque coperto di schifose deformità; nè Domizia,
adultera con Paride istrione.
Giovenale, nella succitata Satira sesta, denunzia che non poche
mogli di cavalieri, di senatori e di più illustri personaggi si
abbandonassero a’ gladiatori ed istrioni, che avevano saputo piacer
loro, e nella terza satira accenna alla deplorevole introduzione nelle
primarie famiglie de’ frutti di questa infame prostituzione, quando
toccando della legge d’Ottone che nell’anfiteatro aveva assegnato i
posti alle varie classi di spettatori, grida:
Exeat inquit,
Si pudor est, et de pulvino surgat equestri,
cujus res legi non sufficit; et sedeant hic
Lenonum pueri quocumque in fornice nati.
Hic plaudat nitidi præconis filius, inter
Pinrirapi cultos juvenes, juvenesque lanistæ [166].
e certa Teja, che dimorava nel boschetto Tarpeo e che ne’ bagordi
avrebbe sfidato il più fiero bevitore,
Candida; sed potæ non satis unus erat [173],
si pose con esse sul letto tricliniare a mensa, serviti dallo schiavo
Ligdamo di vino di Metimno, e facendo accompagnar l’orgia dai
suoni della tibia e dal tamburello, suonata la prima da garzone
egizio, il secondo da donzella di File, isola tra l’Egitto e l’Etiopia. Non
mancava nell’intermezzo il nano buffone co’ suoi lazzi, colle sue
capriole e colle castagnette che scuoteva.
Ma la lampada non dava la fiamma vivace, la tavola cadde, e
quando si pose a giuocar coi dadi, sempre gli usciva il cane, cioè il
punto più disgraziato: indizii tutti codesti di non lieto augurio.
Intanto le baldracche, eccitate dal vino, cantavano alla distesa e si
scoprivano il petto lascivamente a provocare il Poeta; ma Properzio,
sempre il pensiero alla sua Cinzia, non curante di esse, viaggiava
col cuore a Lanuvio.
Quand’ecco, stridono i cardini della porta, s’ode un parapiglia, è
Cinzia, ella stessa che rovescia l’uscio, furibonda si scaglia in mezzo
all’orgia, e primieramente caccia le unghie in faccia a Fille. Teja non
attende che la tempesta si scaraventi pur su di lei, si precipita a fuga
gridando acqua, quasi si trattasse d’incendio, ed a Properzio, che
attonito aveva lasciato cader tosto la tazza colma, Cinzia fa sfregio
al volto colle mani, addenta e sanguina il collo e più specialmente,
come quelli che sieno i più rei, cerca offendergli gli occhi. Quindi fa
sbucar dal letto, dove disotto s’era accovacciato, Ligdamo lo
schiavo, gli strappa di dosso gli abiti e chi sa cosa gli stava per
toccare, se il Poeta supplichevole non ne avesse frenata la furia.
Cinzia allora porge a Properzio, in segno di perdono, a toccare il
piede; ma detta al tempo stesso le seguenti condizioni di pace:
E buttossi allora ad altri e più volgari amori, senza che per altro ne
impegnasse seriamente il cuore. Scrisse sulle ginocchia di queste
figlie del piacere quel codice di voluttà, che intitolò Artis Amatoria,
ma eran lascivie estranee al sentimento; perocchè ai teneri amori
avesse, come dissi, veramente detto addio per sempre e chiusa la
carriera di essi, dicendo:
e l’altro: