Android MVP for Beginners
We have a video player application that we developed as a weekend hobby project which does a few things like slow motion, reverse and zoom. Having done the video listing part of the application with very little emphasis on design and maintainability of the code, soon after adding new features the code became an “embarrassment”. Kept getting crashes and the only solution for those crashes we could come up with was adding a try catch :(.
Needed to make the video listing part of my application crash free, easy to maintain and extend. I had to turn to a design pattern and it was the MODEL VIEW PRESENTER.
I have never professionally written code in Android, so all the explanations below would be from a beginners perspective.
This article is implementation of the ideas I learned from the below article. Please go through the below article to better understand the concepts
https://www.techyourchance.com/mvp-mvc-android-1/
Blueprint for MVP Application
MVP Explained
Like most architectural patterns MVP is open to a lot of variety and experimentation and its implementation can be ambiguous. So you can modify your implementation according to your needs as long as your implementation meets the below objectives.
- Separate the code for the view, which we show to the user like a list, buttons, labels, textbox etc from the business logic which is triggered on user interaction with the view which we call presenter. The data that we show in the view should be provided by another separate module which we call as model. In turn code becomes readable, understandable and maintainable.
- The communication between the view and the model needs to take place through the presenter i.e. The view and model cannot have reference of one another.
- Using this design pattern we should be able to make changes in one components without having the need to change any code in the other two components. Also in case we want to completely replace the view or model with another implementation, that should be possible as well. for example you can use content provider to get list of videos, that tomorrow should be replaceable by sqLite database without change in any other part.
- Maximize the code that can be tested with automation.
Android Activity And MVP
The android framework makes it really easy to start development of any idea that you have in mind, but this structure of code very soon becomes unmanageable with a lot of spaghetti code and classes with different functionalities all mixed into one activity/fragment class.
Now, the android activity seems to give the functionality of view since we do things like setContentView() in OnCreate(). Activity at the same time maintains the android lifecycle events like onCreate() onResume() etc which would be the business logic i.e. presenter.
Another simple example to show how they are entangled
- Register listeners for user’s interactions with application’s UI — View
- Perform actions in response to user’s interactions with application’s UI — Business Logic
Most of you would agree that debugging an Activity code with several lines of code registering UI components and at the same time also having a few lines of business logic embedded here and there is a huge pain.
Now, on the basis of Single Responsibility Principle, we need to assign Activity the role of a View or a Presenter. I decided to use Activity as the Presenter, because activity has the context(which is the god Object that provide access to most platform’s features). This makes Activity a natural choice for keeping the responsibility for business logic. After all we want keep the view to be dumb module that only has the functionality to load the UI elements. For more detail on this topic, you can go through this article explaining why activities are not UI elements.
Implementation of MVP in my App
The complete code is available on github. Please check out android-video-listing-mvp
I will walk through the code of my app and try to explain how I checked the boxes for the objectives of MVP.
Model
Now, This part of the application was the most straight forward to implement. We used ContentProvider provided by Android to get list of videos. As contentProvider is provided by android out of the box, so we needed nothing more than few lines of code to setup contentprovider and query it to get the list of videos. You can refer to VideoListManagerImpl.java for more detail. LoaderManger.LoaderCallbacks was used to get automatic events of videos list updating.
If we latter plan to replace this with my SQLite Database(as it does not return .mov format files). The replacement can be done with minimum friction as the code is structured in MVP format.
Let’s go through how this replacement will work with an example.
The presenter’s interaction with the model(Content Provider) is handled by a separate Manager Class. This Manager class follows the contract of VideoListManager.
Some can argue that the Manager class belongs to the model, I favor Manager class as part of Presenter but do not completely disagree with those who think otherwise, as the long as the code is cleanly separated.
Tomorrow replacing ContentProvider with sqLite will be fairly easy as long as the new manager class implements the above interface(my contract) and updates the presenter with list of videos in the format required by the interface, nothing needs to change anywhere else in my code.
View
We display videos in a tablayout using ListView and ExpandableListView. We used a ViewMvp Interface that returns the root view to the presenter which can be further used for communications between presenter and view for the user interactions.
This ViewMvp interface described above is a very general interface and as the 4 concrete views in the demo application needed a little more functionality like returning the ListView etc, we defined them as sub-interface of the ViewMvp. Check out the implementation VideoListFragmentView to get a better understanding.
Unlike other MVP articles you can find the code here done for a real world application handling complexities like giving animations during swipes, providing functionalities like searching sorting and handling the communication between fragments and activities
This approach of making the view a dumb holder of UI without any logic embedded in it, implemented through an interface also helps us with
- reuse of UI
- unit testing since we are implementing an interface
- any changes in UI going forward will be less error prone.
Adapters, Since we are using a ListView, we need to implement it using an Adapter. We use the well documented ViewHolder pattern that works well to display the list elements inside the ListView. Check the implementation of the adapter here
bindVideoList, all the views implement bindVideoList method, that is used to communicate the updating of the video list, on video addition, deletion, searching and sorting
Presenter
The presenter is the core of the application, it initializes the view and the model, also sets up the communication framework for handling user interaction and model data changes. The logic of searching, sorting, video share, delete, rename and what happens when a user chooses a video, all that business logic goes in this bucket. List of functionalities of the Presenter are
- Interacting with OS
- handling User Input/Requests and producing the result
- handling communication between the View and the Model
- Maintaining the state of the application
- Encapsulate all of the applications business logic
Presenter doing all that does not contain any view implementation details as well as the details of data storage mechanism in the model .
The presenter depends only on the contract which we enforce using interfaces.
Below is an example of how I initialize the view and model in the presenter onCreate() method.
As discussed above Activities and Fragments take up the role of Presenter. The role of presenter is further split to manage the model interaction through the manager class.
Refer to the implementation of the Presenter from here
The other Cool Features of the applications
- The application uses Fragments to show the tabs for different type of views of Video listing. We used the recommended way as described in the android developer articles on how to communicate between fragments and activities by using an interface and having fragment attach to the implementation in onAttach and calling up the interface to communicate with the Activity
- The app also has scrollup Parallax tab implementation
- Functionalities to rename, delete and share videos
- Simple and efficient sorting mechanisms.
- Implementation to get Load Thumbnail Bitmaps and using LRU and Disk Caching
I recommend you to check my git repository for complete implementation details of android video listing in mvp. This has a simple, clean, efficient and very easily extendable implementations of Video Listing Functionality in Android.
Checkout our Video Player
PlayStore Link— Video Player for Slow and Reverse with Zoom And Pan
WebSite — Video Player for Slow and Reverse With Zoom And Pan
If you liked the article, do press the recommend button. Thanks for your time.