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.
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
This component is used to add lifecycle awareness. Lifecycle components includes Lifecycle, LifecycleOwner and LifecycleObserver
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 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 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.
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());
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.
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; } }
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 }); } }
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.
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 }); } }
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:
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().
Represents a table within the database.
Contains the methods used for accessing the database.
@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. }
@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();
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); }
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.
Let us write your business’s growth story by offering innovative, scalable and result-driven IT solutions. Do you have an idea that has a potential to bring a change in the world? Don’t hesitate, share with our experts and we will help you to achieve it.