We know the old android architecture components like Linux kernel, native libraries, android runtime, application framework, and applications.
Google has launched 14 different versions of android OS but one thing to notice is that there was not a good architecture to follow or to maintain your code better. But in now Google I/O has announced a new Android Architecture components that will help us to maintain our code robust, testable, maintainable and easily readable. The new pattern announced by Google is MVVM i.e model view view-model pattern that is reactive and removes lots of boiler plate codes.
Android Architecture Components
There are 4 components now:
- Live Data
- View Model
- Life Cycle
- Room
Let's see all one by one.
1. Live Data
Live data is just an observable data holder that notify observer about the data changes so that we can update the UI easily.
Live data can be of any type like this:
LiveData<List<Your<Model>> myLiveData;
Live data works with Lifecycle component to check the current state of activity like on screen, off screen or destroy so live data update UI only when activity is visible.
2. Life Cycle
We know that live data send an update to UI only when activity is not off screen or destroy. Live data uses 2 lifecycle interfaces for this, that is LifeCycleOwner and LifeCycleObserver.
LifeCycleOwner: These are the fragments or activities.
LifeCycleObserver: This is Lifecycle observer that observe lifecycle owner.
3. View Model
View Model are objects that holds live data and other data for UI and also control configuration changes.
4. Room
we have already discussed this in our previous tutorial, please click on below link:
How to Implement Room Database in Android using RxJava2
Example:
Step 1: Add dependencies in app.gradle
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support:support-v4:25.3.1'
compile 'android.arch.persistence.room:runtime:1.0.0-alpha9-1'
compile 'com.android.support:design:25.3.1'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
compile 'android.arch.lifecycle:extensions:1.0.0-alpha9-1'
testCompile 'junit:junit:4.12'
annotationProcessor 'android.arch.persistence.room:compiler:1.0.0-alpha9-1'
Step 2: Add maven repo in project gradle
allprojects {
repositories {
jcenter()
maven { url 'https://maven.google.com' }
}
}
Step 3: Create Pojo or model class to hold data :
@Entity
public class BookModel {
@PrimaryKey(autoGenerate = true)
public int id;
@ColumnInfo (name = "Name")
public String mBookName;
@ColumnInfo (name = "Price")
public String mBookPrice;
public BookModel(String mBookName, String mBookPrice){
this.mBookName = mBookName;
this.mBookPrice = mBookPrice;
}
public String getmBookName() {
return mBookName;
}
public void setmBookName(String mBookName) {
this.mBookName = mBookName;
}
public String getmBookPrice() {
return mBookPrice;
}
public void setmBookPrice(String mBookPrice) {
this.mBookPrice = mBookPrice;
}
}
We have already discussed about the entity or other annotations of Room library.
Step 4: Now create interface Data access object :
@Dao
public interface BooksDao {
@Query("SELECT * FROM BookModel")
LiveData<List<BookModel>> getBooks();
@Insert(onConflict = REPLACE)
void insertBook(BookModel aBookModel);
}
we have live data here that will update the ui whenever any change will happen in database.
Step 5: Now create abstract database class
@android.arch.persistence.room.Database(entities = BookModel.class,version = 1)
public abstract class Database extends RoomDatabase {
private static Database INSTANCE;
public static Database getDatabase(Context context) {
if (INSTANCE == null) {
INSTANCE =
Room.databaseBuilder(context.getApplicationContext(), Database.class, "books_db")
.build();
}
return INSTANCE;
}
public abstract BooksDao getBooksDao();
}
Step 6: create a view model class that will instantiate database and will provide methods to access live data
public class BooksViewModel extends AndroidViewModel {
private Database mDatabase;
public BooksViewModel(Application application) {
super(application);
mDatabase = Database.getDatabase(application.getApplicationContext());
}
public void addBook(BookModel aBookModel){
new myAsyncTask(mDatabase).execute(aBookModel);
}
private static class myAsyncTask extends AsyncTask<BookModel, Void, Void> {
private Database db;
myAsyncTask(Database appDatabase) {
db = appDatabase;
}
@Override
protected Void doInBackground(final BookModel... params) {
db.getBooksDao().insertBook(params[0]);
return null;
}
}
public LiveData<List<BookModel>> getBooksLiveData(){
return mDatabase.getBooksDao().getBooks();
}
}
Step 7: Create activity to add data in database here we are adding book details like name and price :
public class AddBooksActivity extends AppCompatActivity {
private EditText etBookName;
private EditText etBookPrice;
private Button btnAdd;
private BooksViewModel mAddBookViewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_books);
etBookName = (EditText) findViewById(R.id.etBookName);
etBookPrice = (EditText) findViewById(R.id.etBookPrice);
btnAdd = (Button) findViewById(R.id.btnAdd);
//of is used to instantiate view model provider and get is used to return the model.
mAddBookViewModel = ViewModelProviders.of(this).get(BooksViewModel.class);
btnAdd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (!TextUtils.isEmpty(etBookName.getText().toString()) && !TextUtils.isEmpty(etBookPrice.getText().toString())){
BookModel mBookModel = new BookModel(etBookName.getText().toString(),etBookPrice.getText().toString());
mAddBookViewModel.addBook(mBookModel);
finish();
}
}
});
}
}
XML file for add nook is here:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.tech.bookscollections.AddBooksActivity">
<TextView
android:layout_width="match_parent"
android:gravity="center_horizontal"
android:text="Books Entry"
android:textColor="#223344"
android:textSize="25sp"
android:layout_height="wrap_content" />
<EditText
android:layout_width="match_parent"
android:id="@+id/etBookName"
android:textSize="20sp"
android:layout_marginTop="10dp"
android:layout_height="wrap_content" />
<EditText
android:layout_width="match_parent"
android:id="@+id/etBookPrice"
android:textSize="20sp"
android:layout_marginTop="10dp"
android:layout_height="wrap_content" />
<Button
android:layout_width="match_parent"
android:text="Add"
android:id="@+id/btnAdd"
android:layout_height="wrap_content" />
</LinearLayout>
Step 8: Create main activity to show recycler view. here you can see that you don't need to load whole database every time live data will take care of it.
public class MainActivity extends AppCompatActivity {
private RecyclerViewAdapter recyclerViewAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
Button btnAddMore = (Button) findViewById(R.id.btnAddMore);
recyclerViewAdapter = new RecyclerViewAdapter(new ArrayList<BookModel>());
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(recyclerViewAdapter);
BooksViewModel mBooksViewModel = ViewModelProviders.of(this).get(BooksViewModel.class);
mBooksViewModel.getBooksLiveData().observe(MainActivity.this, new Observer<List<BookModel>>() {
@Override
public void onChanged(@Nullable List<BookModel> bookModels) {
recyclerViewAdapter.addItems(bookModels);
}
});
btnAddMore.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this,AddBooksActivity.class);
startActivity(intent);
}
});
}
}
XML file for main activity is here :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:showIn="@layout/activity_main">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<Button
android:layout_width="wrap_content"
android:id="@+id/btnAddMore"
android:text="Add book"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_margin="10dp"
android:layout_height="wrap_content" />
</RelativeLayout>
and finally this is the adapter class for recycler view :
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.RecyclerViewHolder> {
private List<BookModel> bookModelList;
public RecyclerViewAdapter(List<BookModel> bookModelList) {
this.bookModelList = bookModelList;
}
@Override
public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new RecyclerViewHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.recycler_item, parent, false));
}
@Override
public void onBindViewHolder(final RecyclerViewHolder holder, int position) {
BookModel mBookModel = bookModelList.get(position);
holder.tvBookName.setText(mBookModel.getmBookName());
holder.tvBookPrice.setText(mBookModel.getmBookPrice());
}
@Override
public int getItemCount() {
return bookModelList.size();
}
public void addItems(List<BookModel> bookModelList) {
this.bookModelList = bookModelList;
notifyDataSetChanged();
}
static class RecyclerViewHolder extends RecyclerView.ViewHolder {
private TextView tvBookName;
private TextView tvBookPrice;
RecyclerViewHolder(View view) {
super(view);
tvBookName = view.findViewById(R.id.tvBookName);
tvBookPrice = view.findViewById(R.id.tvBookPrice);
}
}
}
Thanks ! If you have any questions, please feel free to write in comments.
0 Comment(s)