Today we're announcing a guide to Android app architecture along with a
preview of Architecture Components. Rather than reinventing the wheel,
we're also recognizing the work done by popular Android libraries.
A typical Android observation model would be to start observation in onStart() and stop observation in onStop(). This sounds simple enough, but often times you'll have several asynchronous calls happening at once, all managing the lifecycles of their component.
LiveData can be observed by many listeners, each tied to a lifecycle owner such as a Fragment or Activity.
The core framework provides built-in support for working with raw SQL content:
To use Room, you annotate the Java data objects you wish to persist as entities,
create a database containing these entities, and define a DAO class with the SQL
to access and modify the database.
To learn more about Android Architecture, check out:
Opinions not Prescriptions
We know that there's more than one way to write Android applications. What we're providing is a set of guidelines that can help you architect an Android application to work best with the unique ways that Android interacts. The Android framework has well-defined APIs to handle contact points with the OS, such as Activities, but these are entry points into your application, not building blocks for your application architecture; Framework components don't force you to separate your data model from your UI components, or provide a clear way to persist data independent of the lifecycle.Building Blocks
Android Architecture Components work together to implement a sane app architecture, while they individually address developer pain points. The first set of these components helps you:- Automatically manage your activity and fragment lifecycles to avoid memory and resource leaks
- Persist Java data objects to an SQLite database
Lifecycle Components
New lifecycle-aware components provide constructs to tie core components of your applications to lifecycle events, removing explicit dependency paths.A typical Android observation model would be to start observation in onStart() and stop observation in onStop(). This sounds simple enough, but often times you'll have several asynchronous calls happening at once, all managing the lifecycles of their component.
Lifecycle, LifecycleOwner, and LifecycleObserver
The core class for all of this is Lifecycle. It uses an enumeration for the current lifecycle state along with an enumeration for lifecycle events to track the lifecycle status for its associated component.
Lifecycle States and Events
LifecycleOwner
is an interface that returns a Lifecycle object from the getLifecycle()
method, while LifecycleObserver
is a class that can monitor the component's lifecycle events by adding
annotations to its methods. Putting this all together, we can create
lifecycle-aware components that can both monitor lifecycle events and query the
current lifecycle state.public class MyObserver implements LifecycleObserver { public MyObserver(Lifecycle lifecycle) { // Starts lifecycle observation lifecycle.addObserver(this); ... } public void startFragmentTransaction() { // Queries lifecycle state if (lifecycle.getState.isAtLeast(STARTED)) { // perform transaction } } // Annotated methods called when the associated lifecycle goes through these events @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) public void onResume() { } @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) public void onPause() { } } MyObserver observer = new MyObserver(aLifecycleOwner.getLifecycle());
LiveData
LiveData is an observable lifecycle-aware data holder class. Your UI code subscribes to changes in the underlying data, tied into a LifecycleOwner, and LiveData makes sure the observer:- Gets updates to the data while the Lifecycle is in an active state (STARTED or RESUMED)
- Is removed when the LifecycleOwner is destroyed
- Gets up-to-date data when the LifecycleOwner restarts due to a configuration change or is restarted from the back stack
LiveData can be observed by many listeners, each tied to a lifecycle owner such as a Fragment or Activity.
ViewModel
ViewModel is a helper class that contains UI data for an Activity or Fragment that serves to separate view data ownership from UI controller logic. A ViewModel is retained as long as the scope of its Activity/Fragment is alive, including when the Activity/Fragmentis destroyed and recreated due to a configuration change; This allows ViewModel to make UI data available to the recreated activity or fragment instance. Wrapping UI data stored within the ViewModel with LiveData provides the data an observable lifecycle-aware home. LiveData handles the notification side of things while the ViewModel makes sure that the data is retained appropriately.Data Persistence
Room library. Room provides an object-mapping abstraction layer that allows fluent database access while harnessing the full power of SQLite.The core framework provides built-in support for working with raw SQL content:
- There is no compile-time verification of raw SQL queries.
- As your schema changes, you need to update the affected SQL queries manually. This process can be time consuming and error prone.
- You need to write lots of boilerplate code to convert between SQL queries and Java data objects.
Database, Entity, and DAO
There are three major components in Room:- Entity represents the data for a single database row, constructed using an annotated Java data object. Each Entity is persisted into its own table.
- DAO (Data Access Object) defines the methods that access the database, using annotations to bind SQL to each method.
- Database is a holder class that uses annotations to define the list of entities and database version. The class content defines the list of DAOs. It's also the main access point for the underlying database connection.
@Entity public class User { @PrimaryKey private int uid; private String name; // Getters and Setters - required for Room public int getUid() { return uid; } public String getName() { return name; } public void setUid(int uid) { this.uid = uid; } public void setName(String name) { this.name = name; } } @Dao public interface UserDao { @Query("SELECT * FROM user") ListgetAll(); @Insert void insertAll(User... users); } @Database(entities = {User.class}, version = 1) public abstract class AppDatabase extends RoomDatabase { public abstract UserDao userDao(); }
Guide to App Architecture
Today we're launching a Guide to App Architecture that shows how to build a robust, modular, and testable app using Architecture Components. The Guide has three main goals:- Defining principles that apply to Android app development.
- Describing an app architecture that works with those principles.
- Showing how to implement that architecture using Architecture Components.
Just the Beginning
We're planning to continue being opinionated, and to continue to introduce new Architecture Components to make it easier for Android developers to make informed choices when architecting their applications.To learn more about Android Architecture, check out:
0 comments:
Post a Comment