The Problem: Really large and convoluted Activity classes. Hard to read/understand and modify. Hard to test.
The Possible Solution: Model-View-Presenter (perhaps with dependency injection).
And Mock Test Objects!
I’m planning on implementing Model-View-Presenter in my Android application.
This is basically a variant of the Model-View-Controller. In essence, make the Activity
a glorified layout manager and defer any business logic to the Presenter. Another way of looking at the Presenter is that its like an Helper class instantiated within an Activity to do the heavy lifting with the activity providing a interface/callback that the Presenter can use.
I would like to get some community thoughts on this. For example:
What interfaces are implied by this?
What responsibilities would the Model and View have vs. the Presenter.
For Presenter I suppose the Activity would implement the interfaces needed by the Presenter?
What kinds of things should go into the Presenter vs. Activity?
Would a presenter be one-to-one with an Activity? What about an Activity with multiple fragments displaying different widgets each with its own adapter? Do we now need multiple presenters or still just one?
What about Presenter vs. Adapter?
How should a presenter relate to say an Activity with a ListView and a ListViewAdapter?
What goes into the Presenter vs. Adapter?
Should the Presenter pick the Adapter to use? Or should the Activity make this decision?
Should the Presenter process Model Data or the Adapter? Is there a conflict between adapters and presenters? Are adapters presenters? or something less/more. Usually Adapters are just for widgets like ListViews within an Activity. They don’t make the calls that get the data itself I think.
So in model-view-presenter the key thing is really to decides what goes in the presenter vs. other classes and what the communication should be between the presenter and activities, adapters and views/including fragments.
Is Model-View-Presenter just a really bad idea for Android? Or does it fit well with the Android Framework?
Keep in mind there are numerous examples outside Android of very mature SDK’s that still needed a micro-architecture like MVP. In fact examples abound: eg. Flex was very mature SDK for Flash and yet it still needed MVP and MVC frameworks for almost any major app.
EJB needed Spring to simplify and organize it. MFC/Struts etc and the list goes on and on. Why should Android be any different? Why should we assume the SDK has everything needed in the case of Android without a design pattern like MVP?
Nice to know before I spend hundreds of hours on this, please feel free to comment/answer on any part of this question.
Android punishes poor MV(P|C) design more than any platform I’ve ever encountered. Forget the clumsy methods it provides for passing state up and down the activity stack. Get as much state and logic out of your activities as possible. Move it into Services, ContentProviders, and SharedPreferences as appropriate. Try to make your activities pure view. IMO, Services have never been given enough attention in Android tutorials. Even the O’Reilly Programming Android book only gives them a quarter page!
Be wary of extending Application. If you ever start a Service in its own process (e.g., to allow it to be shut down gracefully when an Activity crashes) then the Service will have its own copy of your Application.
Just to provide a reference for others who may be interested. I was thinking the same thing some years before. When we apply MVC/MVVM/Presentation Model to android app, what we really want is to have a clear structured project and more importantly easier for unit tests. At the moment, without an third party framework, you usually have lots of code(like addXXListener(), findViewById()…), which does not add any business value. What’s more, you have to run android unit tests instead of normal JUnit tests, which take ages to run and make unit tests somewhat impractical. For these reasons, some years ago we started an open source project RoboBinding – A data-binding Presentation Model framework for the Android platform. RoboBinding helps you write UI code that is easier to read, test and maintain. RoboBinding removes the need of unneccessary code like addXXListener or so, and shifts UI logic to Presentation Model, which is a pojo and can be tested via normal JUnit tests. RoboBinding itself comes with more than 300 JUnit tests to ensure its quality. Other alternatives: Android-Binding, Bindroid and MvvmCross.