Android Architecture

Android architecture is defined as the, A Guide to android app architecture with libraries for a different task, it helps us to create an app that is robust, testable, maintainable, and has less boilerplate code,

Architecture component is part of Android jetpack

Android jetpack is collection of android software component like data binding, lifecycles, livedata, app component, etc, it makes android development easy because it gives proper architecture to develop an application which has minimal boilerplate code

Android Architecture components

  • DataBinding
  • LifeCycleAwareComponent
  • LiveData
  • Navigation
  • Paging 
  • Room
  • ViewModel
  • WorkManager

LifeCycleAwareComponent :—-

Q-What are LifeCycleAware components?

-Activity/Fragment  is lifecycleowner

Activity —– lifecycle  —– LifeCycleOwner

LifeCycle class uses event and state to determine the lifecycle of the lifecycle owner, Each event in the lifecycle is related to the particular state

LifeCycleObserver:——-

Which observe the activity and keep track of its lifecycle thus lifecycle observer performs Action and action depend on lifecycleowner lifecycle event

Dependency you have to include in your project—

implementation “android.arch.lifecycle:extensions:$lifecycle_version”

 

annotationProcessor “android.arch.lifecycle:compiler:$lifecycle_version”


-> LifeCycle class hold info about lifecycle of LifeCycleOwner

LifeCycle object uses following enumeration to track LifeCycle status

  •  Event 
  •  State

Lifecycle Owner Provides Lifecycle status to LifecycleAware component

LifeCycleObserver registers Lifecycle status to respond and perform and perform the action 

// LifecycleOwner

public class MainActivity extends AppCompatActivity {

private String TAG = this.getClass().getSimpleName();

    @Override

protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        getLifecycle().addObserver(new MainActivityObserver());

    }

    @Override

    protected void onStart() {

        super.onStart();

       Log.i(TAG, "owner onstart");

    }

    @Override

    protected void onResume() {

        super.onResume();

        Log.i(TAG, "owner onResume");

    }

    @Override

    protected void onPause() {

        super.onPause();

      Log.i(TAG, "owner onPause");

    }

    @Override

    protected void onStop() {

        super.onStop();

     Log.i(TAG, "owner onStop");

    }

    @Override

    protected void onDestroy() {

        super.onDestroy();

        Log.i(TAG, "Observer Removed");

        getLifecycle().removeObserver(new MainActivityObserver());

    }

}

public class MainActivityObserver implements LifecycleObserver {

    private String TAG = this.getClass().getSimpleName();

    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)

    public void onCreateEvent() {

        Log.i(TAG, "ON_CREATE Event");

    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)

    public void onStartEvent() {

        Log.i(TAG, "ON_START event");

    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)

    public void onResumeEvent() {

        Log.i(TAG, "ON_RESUME event");

    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)

    public void onPauseEvent() {

        Log.i(TAG, "ON_PAUSE event");

    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)

    public void onStopEvent() {

        Log.i(TAG, "ON_STOP event");

    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)

    public void onDestroyEvent() {

        Log.i(TAG, "ON_DESTROY event");

    }

}

Note:–Lifecycle observer observe the lifecycle event of lifecycle owner(Activity/Fragment)

During the creation of activity  owner lifecycle event execute first, during destruction action the lifecycle observer execute first 

———————————————-ViewModel and LiveData—————————————–

The dependency you have to implement in your project

//ViewModel

    implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"

    // LiveData

    implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"

    // Saved state module for ViewModel

implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"

--->View model is not same as onSaveInstanceState()

--->View model uses for large data such as bitmap or user list

--->View model store and manage UI related data

---> View model Destroy only if the owner activity is completely destroyed, in onCleared()

--->View model Communication layer between Database and UI


Q – why do we need a view model?

when you start developing an application the most common thing you need to handle is configuration changes

like:- when we rotate the device the activity is reloaded thus the old data is loss and new one is created, we need to keep our data safe to do that we use viewmodel,  then the view model provides the data after changes of configuration

-> Action perform during changes of configuration

during the change of configuration (Activity/Fragment destroy) the data goes from activity to model and after recreating of activity/fragment the view model provides the data to UI, Science the activity is created we linked it to view model, using view model provider

public class MainActivity extends AppCompatActivity {

    private String TAG = this.getClass().getSimpleName();

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        Toolbar toolbar = findViewById(R.id.toolbar);

        setSupportActionBar(toolbar);

        FloatingActionButton fab = findViewById(R.id.fab);

        fab.setOnClickListener(new View.OnClickListener() {

            @Override

            public void onClick(View view) {

                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)

                        .setAction("Action", null).show();

            }

        });

        TextView mTextView = findViewById(R.id.tvNumber);

        MainActivityViewModel model = ViewModelProviders.of(this).get(MainActivityViewModel.class);

        String myRandomNumber = model.getNumber();

        mTextView.setText(myRandomNumber);

        Log.i(TAG, "Random Number Set");

    }

}

 

ViewModel Class  ——–

public class MainActivityViewModel extends ViewModel {

    private String TAG = this.getClass().getSimpleName();

    private String myRandomNumber;

    public String getNumber() {

        Log.i(TAG, "Get number");

        if (myRandomNumber == null) {

            createNumber();

        }

        return myRandomNumber;

    }

    private void createNumber() {

        Log.i(TAG, "Create new number");

        Random random = new Random();

        myRandomNumber = "Number: " + (random.nextInt(10 - 1) + 1);

    }

    @Override

    protected void onCleared() {

        super.onCleared();

        Log.i(TAG, "ViewModel Destroyed");

    }

}-


Live data:—-

traditional approach

-> using interface

-> Using Event Bus Such as Otto

-> Live data is the best way to manage the runtime changes of data and reflect that changes to UI (recommended by Google)

Note:- MutableLive Data  extends LiveData

Q-Why we use Mutable live data?

Ans-  Mutable live data have a public getter and setter method, so it will easy to manipulate the data 

->  Live data is an Observable data holder class that keeps data and allow data to be observed

Note ->  Observe LiveData from app components onCreate() method

Benefits of LiveData:–

 —>it keeps the UI updated in case of any changes

 —>it automatically destroyed when associated LifeCycleOwner is destroyed

—>There is no crashes due to stopped activities 

 —>it can be shared by multiple resources

—>It works efficiently when you used it with the view model

Note:- when you move from one activity to another activity the first activity observer stop observing the data

RoomDatabase:-

//room
    implementation "androidx.room:room-runtime:2.2.5"

 

SQLite Vs Room

SQLite:—

-> It Deals with raw queries

-> There  is no Compile time verification of raw SQL queries

-> Lots of boilercode to convert between SQL queries and java data objects

-> SQLite API is low-level, so more time more effectively to build apps

Room:–

->it has No raw queries

-> during Compile time it checks SQLite statements

-> it Maps database object and java objects without boilerplate code

-> using of the room is efficient  When we used it  with ViewModel and live data 

 Q-What is Room?

Room database contains Database layer on top of SQLite, it provides an abstraction layer over SQLite to allow fluent database access, it works on object Relation Mapping library(ORM)

Benefits: – easy caching of relevant pieces of database

Components of Room:-

->Entities

    – it defines the schema of the database table

    – Annotated with @Entity

->DAO

   – it contains a method to access the database

   – Annotated with @Dao

->Database

  -database holder class

  -Annotated with @Database

->Annotating the Java class with @Entity, room generate all the necessary code to create an SQLite table for this object,

->we can turn an integer member variable into an auto-incrementing primary key, By Columns for all, its fields. With @PrimaryKey  and autoGenerate = true, from which we can use to uniquely identify each row in the table.

->We can also specify the tableName if it should be different than the class name.

@Entity(tableName = "users")

public class User {

    @PrimaryKey

    public int id;

    @ColumnInfo(name = "first_name")

    public String firstName;

    @ColumnInfo(name = "last_name")

    public String lastName;

}


@Entity:-generate all necessary code to create an SQLite table for this object as well as column for all this field

UserList.java :------

@Entity(tableName = "user_entity")

public class User{

    @PrimaryKey(autoGenerate = true)

    public   int id;

    public String name;

    public Note(String name, String description, int jobNo) {

        this.name= name;

        this.description = description;

        this.jobNo= jobNo;

    }

    public String description;

    public int jobNo;

}


DAO:-

->We define all database operation in DAO

->we declare all operational method without method body, annotated with @insert,@Updates,@Delete

->For generic, we declare it with @Query, we can pass an SQLite query with from it 

->The RoomDatabase works efficiently with live data because our activity or fragment gets notified as soon as a row in the queried database table changes.

Note: Room does not allow data operation on the main thread

UserDao.java :——

@Dao

public interface UserDao {

    @Insert

    void insert(User);

    @Update

    void update(User details);

    //we can also pass multiple argument

    @Delete

    void delete(User user);

    @Query("DELETE FROM user_entity")

    void deleteAllUser();

    @Query("SELECT *FROM user_entity ORDER BY priority DESC")

    LiveData<List<User>>getAllUser();

}


RoomDatabase:-

-> RoomDatabase is an abstract class that acts as a bridge and connects the entities to their corresponding DAO. Just as in an SQLiteOpenHelper.

->we have to define a version number and a migration strategy. With fallback To Destructive Migration, we can let Room recreate our database if we increase the version number.

 

Leave a Reply