Hi, everybody. If you work as an android developer, you know screen rotation is one of the biggest problems in the Android world. The view destroys when the user rotates the screen. We cannot change this, because it is the default behavior for android OS. Alternatively, what can we do?
The problem has a straightforward solution. I really like easy solutions; my team members know it. We cannot change the behavior of OS. Android destroys your activities and fragments when the user rotates the device. However, we can create an object which lives when the user rotates the device. Move all logic from the view to this class.
Then we need to do next: save all methods which presenter calls on view and re-call them on a new view object. We call this class ViewState.
Moxy is a library that helps implement MVP UI pattern in android projects.
ViewState is an object which implements the interface of your view. Moxy inject viewState field into Presenter. One more plus, the presenter has access to all view methods but not the context.
View and Presenter
Moxy provides the base classes for activities and fragments. Moxy has parent classes for all activities and fragments. Your view interface must extend from MvpView. The presenter must extend from the MvpPresenter
MvpPresenter has a protected method getViewState(), this method returns an instance of the object which implements your view interface.
MvpPresenter has an open protected method, onFirstViewAttach(). This method will be called when view is attached to the presenter first time. I recommend overriding the method and use it for executing calls which load data.
Sometimes android os restores view state. Moxy has strategies to handle all cases.
The most popular strategy. The strategy re-calls each method which a presenter called on the ViewState. But if the presenter calls a method more than one time, the method will re-call one time with the last arguments. It means the new view has the last state.
For instance, the presenter calls a method `printLog(“1”), then printLog(“2”), after screen rotation ViewState will call the method only with the argument “2”.
I use this strategy only for methods which show fragments or start activity. Because android os handles this case without help. The method which uses this strategy would be called only once. If the view does not exist at the moment, the presenter calls the method on ViewState, the method will be called on a new view.
The strategy works like OneExecutionStrategy. The method will be called one time or not be called at all. The method isn’t saved into ViewState.
I use this strategy for mutually exclusive methods. Like a `showProgress()` and `hideProgress()`. For instance, the presenter calls `showProgress()` then `hideProgress()`. The strategy re-calls only `hideProgress()` after screen rotation.
I don’t use AddToEndStrategy and I don’t recommend you use it. The strategy re-calls all method for each new view instance.
Under the hood
How does it work?
Moxy uses code generation. Moxy generates a command class for each view method and ViewState class for each view interface. ViewState implements your view interfaces. Moxy generates ViewState at compile time. Field viewState in base presenter will be initialization by instance of the generated class.
Visit Moxy repository on github and put a star if you use easy way for solving hard task.
Editor: Vova Usachov