The significant part of Android community uses MVP approach to split application business scenario into logic layers. Unfortunately, adding MVP to Android is not an easy task because of Activity and Fragment Lifecycle. Furthermore, adding MVP causes a lot of boilerplates while saving state. Let us* introduce an open source library for implementing MVP into Android applications.
- Painlessly integrate MVP into an application
- A long asynchronous task may deliver results to activity after configuration changes (f.e. rotate) and Activity restart (press back and start again)
- Reduce Activity and Fragment saving state boilerplate (typical for MVP)
- Connect multiple views for presenter (not a canonical MVP feature, but a really useful one)
Model — Presenter — ViewState — View approach
Our application model works according to the following scheme:
The scheme description:
The scheme above is implemented under Moxy. Here is a brief overview of the library’s major parts.
Moxy — MvpPresenter
Every presenter is responsible for its own piece of logic. It should extend MvpPresenter<View extends MvpView>.
To pass in the View command you need to call a method:
public View getViewState()
It stores command in ViewState queue and then dispatches it to the view. Note that one Presenter can be attached to several views! All of those views get this command.
After the first view is attached to the presenter, the presenter invokes a callback:
protected void onFirstViewAttach()
At this callback, you can init your presenter
The presenter has the @InjectViewState annotation for the ViewState binding. A parameterless annotation means that ViewState will be generated automatically.
Moxy — MvpView
Every View interface should extend MvpView. In View, you declare commands (methods) that will be called by a presenter. Commands may have @StateStrategyType annotation. It is used to generate ViewState.
Moxy — MvpViewState
To generate ViewState, View interface and @StateStrategyType annotation is used. ViewState implements this View.
StateStrategyType declares ViewState behaviour strategy after invoking its method. The strategy can change a command queue (f.e. Remove the same command from the queue or clean it). By default AddToEndStrategy is used that puts command to the end of the queue.
Moxy — View Implementation
View Implementation (ViewImpl) should implement View. It also should be able to attach and detach presenters. By default we provide MvpFragment and MvpActivity that have a smart attach-detach mechanism. If you want to use it, you should add @InjectPresenter annotation to the Presenter field.
InjectPresenter annotation also manages Presenter lifetime.
PresenterType.LOCAL means your presenter will be stored only while config is changing.
PresenterType.GLOBAL allows to store presenter for as long as you want. To assess the global presenter you should declare tag parameter in the InjectPresenter annotation. It allows Moxy to map stored presenters and views.
Moxy — Model
Feel free to organize your model-presenter communication. You should only note that presenters work on the Main Thread. So you have to run a long operation on another thread.
I prefer to inject a model into a presenter with Dagger (good method for injecting a model into a presenter is onFirstViewAttach) and make communication using Rx.
Directing data flow
To avoid unexpected behaviour you should follow the interaction order between the components as shown in the graph below.
Moxy is very flexible. That was just a quick overview of the basic functionality.
Of course, you can manually:
- Attach/detach presenters (just skip InjectPresenter annotation and use attach/detach methods)
- Create custom view state (just add your custom view state class to InjectViewState annotation)
- Manage Presenter’s instantiating (there is a PresenterFactory mechanism) and recycling (you have access to PresenterStore)
- Create custom StateStrategyType
More articles to come
Moxy is too complex to describe in a single article. In the upcoming articles I want to discuss:
- Android studio template to generate Presenter-View-ViewImpl classes and its cross connection
- How to use Moxy with stuff like Custom View and Adapters
- Generics in Moxy
Moxy is a flexible open source product. Fill free to comment, create issues and contribute to the Moxy repository. Moxy is available at Maven repository. Learn how to add Moxy to your project on Moxy Github page. You can also check samples at MoxySample Github repository.