Android MVVM Architecture Components using The Movie Database API.
This posting is about how to implement android project based on mvvm architecture using the movie db API. I wanted to implement a simple example project using an open API. But thankfully, we can use movies API for free at the movie db. So I used that and made public a simple project.
This simple project is based on MVVM architecture. And written Unit Test code about business logic.
- 100% kotlin, based with anko
- Architecture Components (Lifecycle, LiveData, ViewModel, Room Persistence)
- Material Design & Animations
- The Movie DB API
- Dagger2 for dependency injection
- Retrofit2 & Gson for constructing the REST API
- BaseRecyclerViewAdapter for implementing adapters and viewHolders
- Mockito-kotlin for Junit mock test
movie_camera: A demo project for The Movie DB based on Kotlin MVVM architecture and material design & animations. …
How to build on your environment
If you want to build the sample project after fork on your computer, you should get an API key from The Movie DB. And add your API key in local.properties file like below.
tmdb_api_key = YOUR_API_KEY
This project is not actually 100% TDD, but I tried a little bit to write Unit Test codes.
- API Service -> API Service Unit Test with API response mock files
- DAO -> DAO Unit Test
- Repository -> Repository Unit Test
- ViewModel -> ViewModel Unit Test
- DI & Refactoring
- Implementing UI & Layouts
Based on MVVM architecture and repository pattern.
1. Configuring the ViewModel
ViewModel is one of the most important things in MVVM architecture. Unlike MVP architecture, it makes the loose coupling between activities and business logic. ViewModels does not have dependencies of UI components. So It makes easier unit testing. And ViewModel holds data about UI and it is lifecycle-aware. It makes easier implementing landscape mode, and we do not need to release observers when the UI component is destroyed.
TvDetailViewModel requests dependency injection using @inject annotation. The constructor receives only a repository, So ViewModel does not know about actual business logic like how-to-get or how-to-save. It makes easier unit testing to ViewModel. And ViewModel just publishes data or get data from UI components using LiveData. LiveData holds data from the repository(fetching from the network or getting from DB), it makes easier implementing landscape screen mode. And next, we should create a ViewModel in activities or fragments. but how should we do? ViewModelProvider.Factory makes it really easier.
And next, we can create the ViewModel just by three lines with Dagger!
Inject instances using AndroidInjection.inject(this).
then viewModelFactory who annotated with @inject will be injected by Dagger. next, declare ViewModel using ViewModelProvider. Wow! we created a new ViewModel!
2. Configuring the Room Persistence
Room is one of the popular database library using SQLite made by Google.
IMO, Room has many advantages. It persists data over configuration changes, based on objected-oriented Modeling, supports migration, and it has really nice synergy with LiveData or Rxjava.
The Room persistence library provides an abstraction layer over SQLite to allow fluent database access while harnessing the full power of SQLite.
Firstly, we should create an entity model with @Entity annotation.
And next, we should create DAO(Database Access Object) with @Dao annotation.
Finally, create Database class extends RoomDatabase with @Database annotation. It’s all! and we can use it right now.
3. Configuring the Repository
The repository is one of the design pattern, defined by Eric Evens. It is one of the most useful and most widely applicable design patterns ever invented. Domain layer request needed data to the repository, and repository tosses data from local repositories like database or SharedPreferences. It makes loose coupling between ViewModel, so easier writing unit test code to ViewModel and business logic.
@Singleton annotation makes DiscoverRepository can be injected by Dagger. And requests dependency injection using @inject annotation on the constructor. So we can get network service and DAO singleton instances without initializing by yourself.
4. Unit Testing
If we can, TDD is the best. Or not, we should write unit test codes. Unit Testing provides numerous benefits including finding software bugs early, facilitating change, simplifying integration, and providing a source of documentation. In this project, I used mockito-kotlin.
mockito-kotlin include original mockito library. And it has some nice expression about verifying like whenever than `when`. I did Unit Testing about Api Services, DAO, ViewModels, Repositories or etc.
5. Implementing Circular Revealed Animation
I implemented Activity Extension for using circular revealed animation on activities.
Circular revealed animation can be used over API 21. So we have to check the device version before using. As you can see, requestGlideListener extension is for use with Glide.
If this posting was helped, please give a star at GitHub!