Get a Free Quote
Our Blog

All You Need to Know About Android Architecture Components

Bhavdip Dhameliya
February 21, 2018

Architecture Components

Architecture is a steady plan which needs to be made before the development process starts. Architecture components keep application organized, ties all component together and provide a collection of libraries that help you to design robust, verifiable and maintainable applications. Android’s new architecture suggests some key principles to create an ideal application with security and avoid bloated classes that are difficult to maintain and test.

Building Blocks

Basic examples for building blocks are Activity, View, Intents, Services, Fragments, Manifest File, AVD (Android Virtual Device). These blocks are the representation of rational application’s component architecture and also are marks of developer pain points.

The first set helps you with

  • Automatically manage your activity and fragment lifecycles to avoid memory and resource leaks
  • Persist Java data objects to an SQLite database

Components:

1. Lifecycle Components

This component is used to add lifecycle awareness. Lifecycle components includes Lifecycle, LifecycleOwner and LifecycleObserver

Lifecycle

So far lifecycle is an abstract class managed by the system itself. But in the current scenario, Lifecycle identify component’s state and behave & end task accordingly at the appropriate time.

LifecycleOwner

LifecycleOwner is an interface that can implement to get a lifecycle object from the getLifecycle() method. ProcessLifecycleOwner is useful when you want to manage the lifecycle of a whole process.

LifecycleObserver

LifecycleObserver observes LifecycleOwner components like Activities and Fragments. It receives LifecycleOwner.Event and react to them through the annotation methods.

By implementing this all together, we can create Lifecycle aware application.

  • Implementing Lifecycle observer

public class TestObserver implements LifecycleObserver {

public MyObserver(Lifecycle lifecycle) {

// Starts lifecycle observation

lifecycle.addObserver(this);

...

}

// 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() {

}

}

Now we can use this observer in our app component, using following implementation TestObserver observer = new TestObserver(aLifecycleOwner.getLifecycle());

2. LiveData

LiveData component is a data holder that contains a value that can be observed. With livedata whenever Activity or Fragment updated we will get notified so your UI will be always updated. It is a wrapper around your typical models that notify observers when something changes in that model. The Main advantage of livedata is no more memory leaks and NullPointerExceptions due to unexisting views.

  • Create LiveData objects

public class MyViewModel extends ViewModel {
// Create a LiveData with a String
private MutableLiveData<String> mData;
public MutableLiveData<String> getData() {
if ( mData == null) {
mData = new MutableLiveData<String>();
}
return mData;
}
}
  • Observe LiveData objects

The following code illustrates how to observe LiveData object:
public class MyActivity extends AppCompatActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyViewModel model = ViewModelProviders.of(this).get(MyViewModel .class);
model.getData().observe(this, data -> {
// update UI
});
}
}

3. View Model

ViewModel useful to provide and maintain data for your UI components (Activity or Fragment) in a lifecycle conscious way. It is able to survive through the configuration changes. So if you destroy activity or change your phone orientation you won’t lose ViewModel and data. Due to LiveData instance that is placed under ViewModel class, the input from our end isn’t required.

You don’t need to worry about UI lifecycle of holder data in UI. ViewModel will be build automatically through a factory and you don’t require to handle creating it and demolishing on your own.

  • Implement a ViewModel

It’s illustrated by the following sample code:
public class MyViewModel extends ViewModel {
private MutableLiveData<List<Students>> students;
public LiveData<List<Students>> getStudents () {
if ( students == null) {
students = new MutableLiveData<List<Students>>();
loadStudents();
}
return students;
}
private void loadStudents () {
// Do an asynchronous operation to fetch students.
}
}

You can access this list from an activity as follows:

public class MyActivity extends AppCompatActivity {
public void onCreate(Bundle savedInstanceState) {
// Create a ViewModel the first time the system calls an activity's onCreate() method.
// Re-created activities receive the same MyViewModel instance created by the first activity.
MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);
model.getStudents ().observe(this, students -> {
// update UI
});
}
}

4. Room

Room is a database library & a great alternative for SQLite database. To use SQLite database it is always necessary to write a lot of boilerplate. We can define database by adding annotations in Model class. The library helps to create a cache of app’s data on a device. It is much similar to OrmLite.

There are 3 major components in Room:

a. Database

As your app is persisted, relational data and contains the database holder, It Serves as the chief access point for the underlying connection to the class that’s annotated with @Database should satisfy the following conditions:

Be an abstract class that extends RoomDatabase.

Include the list of entities connected with the database incorporating the annotation.

It returns the class that is annotated with @Dao and contains an abstract method that has 0 arguments.

While at the runtime, you can get an instance of database through calling Room.inMemoryDatabaseBuilder() or else Room.databaseBuilder().

b. Entity

Represents a table within the database.

c. DAO

Contains the methods used for accessing the database.

  • Creating entity

@Entity
public class User {
@PrimaryKey
private int uid;
@ColumnInfo(name = "first_name")
private String firstName;
@ColumnInfo(name = "last_name")
private String lastName;

// Getters and setters are ignored for brevity,
// but they're required for Room to work.
}
  • Create database

@Database(entities = {User.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
private static AppDatabase INSTANCE;
public static AppDatabase getDatabase(Context context) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.getApplicationContext(), AppDatabase.class, "my_db").build();
}
return INSTANCE;
}
}

This class is used to create the database and get an instance of it. We create the database using following code.

Room.databaseBuilder(context.getApplicationContext(), AppDatabase.class, “my_db”).build();

  • Create the Data Access Object

Annotate the class with the @Dao annotation. A class implementation will then be generated by Room that implements the methods defined in the interface (very similar to how Retrofit works).

@Dao
public interface UserDao {
@Query("SELECT * FROM user")
List<User> getAll();
@Query("SELECT * FROM user WHERE uid IN (:userIds)")
List<User> loadAllByIds(int[] userIds);

@Query("SELECT * FROM user WHERE first_name LIKE :first AND "
+ "last_name LIKE :last LIMIT 1")
User findByName(String first, String last);

@Insert
void insertAll(User... users);

@Delete
void delete(User user);
}

Conclusion

This article gives you a basic knowledge of android architecture components. We have tried to include all topics related to newly proposed android architecture which solve all relevant issues which are faced by the developer while application development. Still, if you find any issues, consider Hire Android Developer of Elsner Technology.