MVVM and DataBinding: Android Design Patterns
This article describes the MVVM Design Pattern and its components, data binding, and other design patterns and architectural concepts for the Android platform. By Matei Suica.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
MVVM and DataBinding: Android Design Patterns
30 mins
- Getting Started
- Understanding Design Patterns
- Using Architectural Design Patterns
- Common Architectural Design Patterns in Android
- MVC and MVP
- Taking the Next Step: MVVM
- Understanding MVVM Components
- Defining the Role of the View
- Defining the Model
- Finding the ViewModel’s Place in MVVM
- Improving Testability
- Hiding Behind Interfaces and Dependency Injection
- Testing Each Component
- Best practices in Testing MVVM
- Adding Android’s Architecture Components
- Using DataBinding
- Adding Android’s own ViewModel
- Loose Coupling with LiveData
- The Database in the Room
- Searching For More
- Clean Architecture
Loose Coupling with LiveData
Jetpack also provides the LiveData class. LiveData is just the Observer pattern improved with lifecycle awareness. Most of the problems in Android development come from lifecycle handling. Developers that use LiveData are less likely to have:
To use LiveData, first create your LiveData object in your ViewModel:
- Memory leaks
- Crashes
- Outdated UI
To use LiveData, first create your LiveData object in your ViewModel:
class ProfileViewModel : ViewModel() {
val uiModel: MutableLiveData<UiModel> by lazy {
MutableLiveData< UiModel >()
}
}
After that, connect your View to this LiveData. In your Activity or Fragment, after you’ve created the ViewModel, add this:
viewModel.uiModel.observe(this, Observer<UiModel>{ uiModel ->
// update UI
})
The Database in the Room
The database we discussed earlier named Room is also a Jetpack component. Using Room in your Android app is straightforward. There are three types of classes that you need to write:
- Entities
- Data access objects
- Databases
Entities
Entities are POJOs (Plain-Old-Java-Objects) with annotations for column names and a primary key:
@Entity
data class User(
@PrimaryKey var uid: Int,
@ColumnInfo(name = "first_name") var firstName: String?,
@ColumnInfo(name = "last_name") var lastName: String?
)
Data Access Objects
Usually, each entity has its own data access object (DAO). The DAO implements the CRUD operations, as well as other helpful methods.
@Dao
interface UserDao {
// Create
@Insert
fun insert(user: User)
// Read
@Query("SELECT * FROM user")
fun getAll(): List<User>
// Update
@Update
fun update(user: User)
// Delete
@Delete
fun delete(user: User)
}
Here, UserDao
, has been given each of the CRUD operations tagged with the corresponding annotation.
The best thing about Jetpack components is that they work great together. For example, Room can also return LiveData
objects.
// Read
@Query("SELECT * FROM user")
fun getAll(): LiveData<List<User>>
Cool, huh? This method is lifecycle aware and will propagate changes in a reactive way.
Next up for using Room, you need to create the database.
Database
The database interface needs to know what entities it will have. This lets Room generate the appropriate classes and methods.
@Database(entities = arrayOf(User::class), version = 1)
abstract class MvvmDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
}
Room also handles the versioning of your database. That’s what the second parameter version
is for. It will help you run migrations when you upgrade the database.
Lastly, you need to initialize the database when the app starts:
val db = Room.databaseBuilder(
applicationContext,
MvvmDatabase::class.java, "mvvm-article"
).build()
You provide the builder a context, the database class, and a name for the database file, e.g. “mvvm-article”.
Searching For More
MVVM is not the end of the story for architectural design patterns. There are a number of other patterns that come in handy on Android, especially as the size of your app grows.
Clean Architecture
In 2012, the concept of a Clean Architecture was developed. Since then, every framework community has tried to include a variation of it.
This concept has four layers:
Where to Go From Here?
VIPER
Clean Architecture separates the code even better than MVVM. That doesn’t mean MVVM is not good, but it is not necessarily as “clean” as it could be. For example, the Model in MVVM can sometimes contain adapters and frameworks. But in Clean Architecture, these are separated out.
The most important thing to remember in Clean Architecture is The Dependency Rule. This rule says that source code dependencies can only point inwards in the diagram above, towards the center. Nothing in an inner circle can know anything at all about something in an outer circle.
VIPER is a design pattern that the iOS community developed for their projects. It’s their way of implementing Clean Architecture on iOS.
VIPER stands for: View, Interactor, Presenter, Entity, Router.
As you can see, there are some new components that appear in this acronym. It also suggests that VIPER is a descendant of MVP, not MVVM.
Indeed, you can think of VIPER as MVP with an Interactor and a Router.
The Interactor handles part of the Presenter’s responsibilities in MVP. The business logic moves into the Interactor, leaving the UI events and display to the Presenter.
However, this leaves one problem with the View. The View still handles all the routing between modules. That’s where the Router comes in.
In Android, having a Router to handle navigation was tricky. The developer can’t create Activity instances, because the framework does that. There are workarounds so that a Router can be created with Activity instances too. But Google recently announced Fragment improvements in the Support Library and recommends using them, and Fragments can be instantiated by the developer.
Combined with a Single Activity app structure, the Router can take its rightful place in the VIPER design pattern for Android. With Fragments, Routers can have full power over navigating through modules.
That’s a lot of information that you’ve covered in this article!
You now have a good understanding of what design pattens are in software development, with a focus on architectural design patterns.
You know about the most important patterns out there, and the weaknesses of each one. And the most important thing of all: You now know how to implement MVVM, how to test it, and how to use Android’s Architecture Components from Android Jetpack to get the most out of MVVM.
Good job keeping up with all these patterns and components!
To dive deeper into MVVM, you can check out the MVVM on Android video course. You’ll learn more about each of the MVVM’s components and you can practice the design pattern in small challenges.
If you want to know more about the Google’s components that can help you get the most out of MVVM, read the Android Architecture Component: Getting started tutorial and all the screencasts related to them.
To learn more about Dependency injection you can watch the Dependency Injection with Koin screencast. If you prefer Dagger2, you can read Dependency Injection in Android with Dagger2 and Kotlin. Or watch the screencasts Getting Started with Dagger and Dagger Network Injection.
Even though it’s iOS based, the Design Patterns by Tutorials book covers many of the patterns mentioned in this article.
Finally, design patterns don’t really change much from platform to platform; just the specific code examples and implementation may vary. Be sure to check out the upcoming Advanced App Architecture book for Android for more details on MVP, MVVM, and other architectural patterns on Android.
If you have any questions or comments, please join the forum discussion below!
- Entities
- Use cases
- Interface adapters
- Frameworks and drivers
Clean Architecture separates the code even better than MVVM. That doesn’t mean MVVM is not good, but it is not necessarily as “clean” as it could be. For example, the Model in MVVM can sometimes contain adapters and frameworks. But in Clean Architecture, these are separated out.
The most important thing to remember in Clean Architecture is The Dependency Rule. This rule says that source code dependencies can only point inwards in the diagram above, towards the center. Nothing in an inner circle can know anything at all about something in an outer circle.
VIPER
VIPER is a design pattern that the iOS community developed for their projects. It’s their way of implementing Clean Architecture on iOS.
VIPER stands for: View, Interactor, Presenter, Entity, Router.
As you can see, there are some new components that appear in this acronym. It also suggests that VIPER is a descendant of MVP, not MVVM.
Indeed, you can think of VIPER as MVP with an Interactor and a Router.
The Interactor handles part of the Presenter’s responsibilities in MVP. The business logic moves into the Interactor, leaving the UI events and display to the Presenter.
However, this leaves one problem with the View. The View still handles all the routing between modules. That’s where the Router comes in.
In Android, having a Router to handle navigation was tricky. The developer can’t create Activity instances, because the framework does that. There are workarounds so that a Router can be created with Activity instances too. But Google recently announced Fragment improvements in the Support Library and recommends using them, and Fragments can be instantiated by the developer.
Combined with a Single Activity app structure, the Router can take its rightful place in the VIPER design pattern for Android. With Fragments, Routers can have full power over navigating through modules.
Where to Go From Here?
That’s a lot of information that you’ve covered in this article!
You now have a good understanding of what design pattens are in software development, with a focus on architectural design patterns.
You know about the most important patterns out there, and the weaknesses of each one. And the most important thing of all: You now know how to implement MVVM, how to test it, and how to use Android’s Architecture Components from Android Jetpack to get the most out of MVVM.
Good job keeping up with all these patterns and components!
To dive deeper into MVVM, you can check out the MVVM on Android video course. You’ll learn more about each of the MVVM’s components and you can practice the design pattern in small challenges.
If you want to know more about the Google’s components that can help you get the most out of MVVM, read the Android Architecture Component: Getting started tutorial and all the screencasts related to them.
To learn more about Dependency injection you can watch the Dependency Injection with Koin screencast. If you prefer Dagger2, you can read Dependency Injection in Android with Dagger2 and Kotlin. Or watch the screencasts Getting Started with Dagger and Dagger Network Injection.
Even though it’s iOS based, the Design Patterns by Tutorials book covers many of the patterns mentioned in this article.
Finally, design patterns don’t really change much from platform to platform; just the specific code examples and implementation may vary. Be sure to check out the upcoming Advanced App Architecture book for Android for more details on MVP, MVVM, and other architectural patterns on Android.
If you have any questions or comments, please join the forum discussion below!
Clean Architecture separates the code even better than MVVM. That doesn’t mean MVVM is not good, but it is not necessarily as “clean” as it could be. For example, the Model in MVVM can sometimes contain adapters and frameworks. But in Clean Architecture, these are separated out.
The most important thing to remember in Clean Architecture is The Dependency Rule. This rule says that source code dependencies can only point inwards in the diagram above, towards the center. Nothing in an inner circle can know anything at all about something in an outer circle.
VIPER
VIPER is a design pattern that the iOS community developed for their projects. It’s their way of implementing Clean Architecture on iOS.
VIPER stands for: View, Interactor, Presenter, Entity, Router.
As you can see, there are some new components that appear in this acronym. It also suggests that VIPER is a descendant of MVP, not MVVM.
Indeed, you can think of VIPER as MVP with an Interactor and a Router.
The Interactor handles part of the Presenter’s responsibilities in MVP. The business logic moves into the Interactor, leaving the UI events and display to the Presenter.
However, this leaves one problem with the View. The View still handles all the routing between modules. That’s where the Router comes in.
In Android, having a Router to handle navigation was tricky. The developer can’t create Activity instances, because the framework does that. There are workarounds so that a Router can be created with Activity instances too. But Google recently announced Fragment improvements in the Support Library and recommends using them, and Fragments can be instantiated by the developer.
Combined with a Single Activity app structure, the Router can take its rightful place in the VIPER design pattern for Android. With Fragments, Routers can have full power over navigating through modules.
Where to Go From Here?
That’s a lot of information that you’ve covered in this article!
You now have a good understanding of what design pattens are in software development, with a focus on architectural design patterns.
You know about the most important patterns out there, and the weaknesses of each one. And the most important thing of all: You now know how to implement MVVM, how to test it, and how to use Android’s Architecture Components from Android Jetpack to get the most out of MVVM.
Good job keeping up with all these patterns and components!
To dive deeper into MVVM, you can check out the MVVM on Android video course. You’ll learn more about each of the MVVM’s components and you can practice the design pattern in small challenges.
If you want to know more about the Google’s components that can help you get the most out of MVVM, read the Android Architecture Component: Getting started tutorial and all the screencasts related to them.
To learn more about Dependency injection you can watch the Dependency Injection with Koin screencast. If you prefer Dagger2, you can read Dependency Injection in Android with Dagger2 and Kotlin. Or watch the screencasts Getting Started with Dagger and Dagger Network Injection.
Even though it’s iOS based, the Design Patterns by Tutorials book covers many of the patterns mentioned in this article.
Finally, design patterns don’t really change much from platform to platform; just the specific code examples and implementation may vary. Be sure to check out the upcoming Advanced App Architecture book for Android for more details on MVP, MVVM, and other architectural patterns on Android.
If you have any questions or comments, please join the forum discussion below!