Recently I took over an android project which is built on top of MVP. While simple screens are quite straight forward and easy to read and maintain, the more complex parts of the app are not. Multiple inheritance levels have caused me days of switching between classes, trying to find out how the information flow is actually working.
Here one example of the more problematic hierarchies:
Since we use MVP, naturally there is another presenter class and another view class for each of the classes in the diagram.
So I did some research and found this article: Composition vs Inheritance in MVP
and it's basically saying that composition should be favoured over inheritance in this situation.
What it isn't saying is how to apply that in android. I thought about it for a while, but can't come up with a nice pattern. I could do custom views, but how would they use presenters in the end?
Inheritance, although quite powerful, is quite easy to misuse, and when the inevitable happens, i.e change in requirements, inheritance is highly susceptible to break the open-closed principle due to its inflexibility. The programmer is bound to modify the existing classes which in turn breaks the client code.
This is the reason why composition is usually favored over inheritance. It provides more flexibility with changing requirements.
This design principle says exactly that:
Encapsulate what varies.
Identify the aspect of your code that varies and separate them from
what stays the same. This way we can alter them without affecting the rest of the code.
Moving on to your problem, the first thing that came to my mind after I read your question was: Why not use Strategy Pattern!
The approach you can take is:
BaseMapViewFragment will contain all the code that is common to all derived classes. Have separate Interfaces for different kinds of behaviors(things that vary). You can create concrete behavior classes according to your requirements. Introduce those behavior interfaces as class fields of BaseMapViewFragment. Now classes that extend the BaseMapViewFragment will initialize the required behaviors with concrete behavior classes.
Whatever I said in the above paragraph might be confusing (my english isn't that good either :D), but I just explained the working of the Strategy pattern, nothing more.
There is another design principle at play here:
Program to an interface, not an implementation. The Strategy pattern uses it to implement the code that varies.
I've been in a similar situation. What I ended up doing was taking out functionality from "Base" into separate classes then use it as composition. It was also related to using Maps in a similar structure.
You can create a new class MyAppMapView, it could extend a FrameLayout (or whatever best for your layout). This can contain all of your Map related code (including MapView), you can have custom MapView related functions here like onStart(), onResume(), onPause(), onStop(). Also, you can put everything related to maps here like markers, lines etc.
Once you have that in place you can just use new MyAppMapView() (or add it in xml using com.example.MyAppMapView) in your MapViewSimpleFragment and MapViewDetailsFragment and since both of these classes would be composing your custom MyAppMapView class, you can call all map related functions from Fragments like drawing markers, lines, onStart() etc.
Many Android apps include a BaseActivity class of their own, which all Activities in the app extend. This is useful because it gives a central place to put functionality that's common across most/all activities. The main drawback of having a BaseActivity is you are then unable to use any of the Activity subclasses (ListActivity, etc.).
One alternative is to have an ActivityDelegate. This gives a central place for functionality while still allowing you to use Activity subclasses. It's also arguably more testable, since it uses composition instead of inheritance.
Both of these solutions potentially lead to a lot of spaghetti code when the BaseActivity/ActivityDelegate gets too large and convoluted. A possible solution to this is to use the delegate pattern, but split the functionality into many different Delegates. This reduces spaghetti code in the Delegates, but then the Activities get more complicated - they're now trying to forward their on* methods to lots of different Delegates instead of just one.
A possible solution to all of these problems is to use a Delegate Manager. The Delegate Manager keeps track of all the smaller Delegates in the app. Activities forward their on* methods to the Delegate Manager, which forwards them on to all of the individual Delegates. This accomplishes all of the following:
Dedupes code - all common functionality gets placed into one of the Delegates
Allows use of Activity subclasses
Simple code in all Activities - all on* methods are forwarded to just one class
Easily testable - it's simple to mock out everything around the Delegates and the Delegate Manager for unit tests
Has anyone tried using this pattern before? If so, how did it go?
As far as I understand, you're talking about one single DelegateManager object for the entire application. If this is the case, you can use registerActivityLifecycleCallbacks, see http://developer.android.com/reference/android/app/Application.html#registerActivityLifecycleCallbacks%28android.app.Application.ActivityLifecycleCallbacks%29
If you're on < API level 14 you need to take a look at: https://github.com/BoD/android-activitylifecyclecallbacks-compat.
registerActivityLifecycleCallbacks lets you hook into the activities onXXX lifecycle methods.
Doing this certainly has all the benefits you described:
decoupling being usable only when you actually need to repeat behavior which is kinda seldom for controller+view logic tied in together the way Activity works.
Removing inheritance is nice if you have activities you might reuse - but I've never had to do it before. But I guess a good use-case would be your home-cooked activity for handling settings or something like it that needs app-wide L&F & behavior.
On the top of my head I can think of these downsides:
Using listeners all over the place can blur path of the application activity/call hierarchy and can make the code hard to understand. This holds true for all listener/dispatcher type of programming. It's a powerful tool, but handle it with care.
It can introduce a lot of (as you mention) boilerplate/spaghetti code if all you do is pass on to lifecycle listeners/delegates.
it is your responsibility to de-register yourself from the Application with Application.unregisterActivityLifecycleCallbacks. I don't think there's a good way around it,
Personally I haven't used this design-pattern much for lifecycles, but it might be worthwhile for some use-cases. For example:
ApplicationLifecycleLogger: Every time you create/resume/pause... an activity, you logcat or something else making debugging lifecycles a tad bit easier.
If for example someone goes into an activity he/she is not allowed to go into due to model state of some sort (e.g. a ringing alarm -> can't go into AlarmEditActivity), you could do finish() there.
Passing object state across activity boundaries without Parcelable:s and screen rotation changes. Usually this is implemented with a Map in Application or some static field somewhere. You can do this by letting the delegators hold state.
Also, take a look at: Is there a design pattern to cut down on code duplication when subclassing Activities in Android?
I hope this was helpful =)
Is it possible to implement the model–view–controller pattern in Java for Android?
Or is it already implemented through Activities? Or is there a better way to implement the MVC pattern for Android?
In Android you don't have MVC, but you have the following:
You define your user interface in various XML files by resolution, hardware, etc.
You define your resources in various XML files by locale, etc.
You extend clases like ListActivity, TabActivity and make use of the XML file by inflaters.
You can create as many classes as you wish for your business logic.
A lot of Utils have been already written for you - DatabaseUtils, Html.
There is no universally unique MVC pattern. MVC is a concept rather than a solid programming framework. You can implement your own MVC on any platform. As long as you stick to the following basic idea, you are implementing MVC:
Model: What to render
View: How to render
Controller: Events, user input
Also think about it this way: When you program your model, the model should not need to worry about the rendering (or platform specific code). The model would say to the view, I don't care if your rendering is Android or iOS or Windows Phone, this is what I need you to render.
The view would only handle the platform-specific rendering code.
This is particularly useful when you use Mono to share the model in order to develop cross-platform applications.
The actions, views and activities on Android are the baked-in way of working with the Android UI and are an implementation of the model–view–viewmodel (MVVM) pattern, which is structurally similar (in the same family as) model–view–controller.
To the best of my knowledge, there is no way to break out of this model. It can probably be done, but you would likely lose all the benefit that the existing model has and have to rewrite your own UI layer to make it work.
After some searching, the most reasonable answer is the following:
MVC is already implemented in Android as:
View = layout, resources and built-in classes like Button derived from android.view.View.
Controller = Activity
Model = the classes that implement the application logic
(This by the way implies no application domain logic in the activity.)
The most reasonable thing for a small developer is to follow this pattern and not to try to do what Google decided not to do.
PS Note that Activity is sometimes restarted, so it's no place for model data (the easiest way to cause a restart is to omit android:configChanges="keyboardHidden|orientation" from the XML and turn your device).
EDIT
We may be talking about MVC, but it will be so to say FMVC, Framework--Model--View--Controller. The Framework (the Android OS) imposes its idea of component life cycle and related events, and in practice the Controller (Activity/Service/BroadcastReceiver) is first of all responsible for coping with these Framework-imposed events (such as onCreate()). Should user input be processed separately? Even if it should, you cannot separate it, user input events also come from Android.
Anyway, the less code that is not Android-specific you put into your Activity/Service/BroadcastReceiver, the better.
There is no single MVC pattern you could obey to. MVC just states more or less that you should not mingle data and view, so that e.g. views are responsible for holding data or classes which are processing data are directly affecting the view.
But nevertheless, the way Android deals with classes and resources, you're sometimes even forced to follow the MVC pattern. More complicated in my opinion are the activities which are responsible sometimes for the view, but nevertheless act as an controller in the same time.
If you define your views and layouts in the XML files, load your resources from the res folder, and if you avoid more or less to mingle these things in your code, then you're anyway following an MVC pattern.
You can implement MVC in Android, but it is not "natively supported" and takes some effort.
That said, I personally tend towards MVP as a much cleaner architectural pattern for Android development. And by saying MVP I mean this:
I have also posted a more detailed answer here.
After playing with the various approaches to MVC/MVP implementation in Android, I came up with a reasonable architectural pattern, which I described in a this post: MVP and MVC Architectural Patterns in Android.
The best resource I found to implement MVC on Android is this post:
I followed the same design for one of my projects, and it worked great. I am a beginner on Android, so I can't say that this is the best solution.
I made one modification: I instantiated the model and the controller for each activity in the application class so that these are not recreated when the landscape-portrait mode changes.
I agree with JDPeckham, and I believe that XML alone is not sufficient to implement the UI part of an application.
However, if you consider the Activity as part of the view then implementing MVC is quite straightforward. You can override Application (as returned by getApplication() in Activity) and it's here that you can create a controller that survives for the lifetime of your application.
(Alternatively you can use the singleton pattern as suggested by the Application documentation)
MVC- Architecture on Android
Its Better to Follow Any MVP instead MVC in android. But still according to the answer to the question this can be solution
Description and Guidelines
Controller -
Activity can play the role.
Use an application class to write the
global methods and define, and avoid
static variables in the controller label
Model -
Entity like - user, Product, and Customer class.
View -
XML layout files.
ViewModel -
Class with like CartItem and owner
models with multiple class properties
Service -
DataService- All the tables which have logic
to get the data to bind the models - UserTable,
CustomerTable
NetworkService - Service logic binds the
logic with network call - Login Service
Helpers -
StringHelper, ValidationHelper static
methods for helping format and validation code.
SharedView - fragmets or shared views from the code
can be separated here
AppConstant -
Use the Values folder XML files
for constant app level
NOTE 1:
Now here is the piece of magic you can do. Once you have classified the piece of code, write a base interface class like, IEntity and IService. Declare common methods. Now create the abstract class BaseService and declare your own set of methods and have separation of code.
NOTE 2: If your activity is presenting multiple models then rather than writing the code/logic in activity, it is better to divide the views in fragments. Then it's better. So in the future if any more model is needed to show up in the view, add one more fragment.
NOTE 3: Separation of code is very important. Every component in the architecture should be independent not having dependent logic. If by chance if you have something dependent logic, then write a mapping logic class in between. This will help you in the future.
Android UI creation using layouts, resources, activities and intents is an implementation of the MVC pattern. Please see the following link for more on this - http://www.cs.otago.ac.nz/cosc346/labs/COSC346-lab2.2up.pdf
mirror for the pdf
Android's MVC pattern is (kind-of) implemented with their Adapter classes. They replace a controller with an "adapter." The description for the adapter states:
An Adapter object acts as a bridge between an AdapterView and the
underlying data for that view.
I'm just looking into this for an Android application that reads from a database, so I don't know how well it works yet. However, it seems a little like Qt's Model-View-Delegate architecture, which they claim is a step up from a traditional MVC pattern. At least on the PC, Qt's pattern works fairly well.
Although this post seems to be old, I'd like to add the following two to inform about the recent development in this area for Android:
android-binding - Providing a framework that enabes the binding of android view widgets to data model. It helps to implement MVC or MVVM patterns in android applications.
roboguice - RoboGuice takes the guesswork out of development. Inject your View, Resource, System Service, or any other object, and let RoboGuice take care of the details.
Model View Controller (MVC)
Description:
When we have to main large projects in the software development, MVC
is generally used because it’s a universal way of organizing the
projects.
New developers can quickly adapt to the project
Helps in development of big projects and cross platform too.
The MVC pattern is essentially this:
Model: What to display. This can be the data source (Ex: Server, Raw
data in the app)
View: How it’s displayed. This can be the xml. It is thus acting as a
presentation filter. A view is attached to its model (or model part)
and gets the data necessary for the presentation.
Controller: Handling events like user input. This be the activity
Important feature of MVC: We can modify Either the Model or View or Controller still not affecting the other ones
Say we change the color in the view, size of the view or the position
of the view. By doing so it won’t affect the model or the controller
Say we change the model (instead of data fetched from the server
fetch data from assets ) still it won’t affect the view and
controller
Say we change the Controller(Logic in the activity) it won’t affect
the model and the view
It was surprising to see that none of the posts here answered the question. They are either too general, vague, incorrect or do not address the implementation in android.
In MVC, the View layer only knows how to show the user interface (UI). If any data is needed for this, it gets it from the Model layer. But the View does NOT directly ask the model to find the data, it does it through the Controller. So the Controller calls the Model to provide the required data for the View. Once the data is ready, the Controller informs the View that the data is ready to be acquired from the Model. Now the View can get the data from the Model.
This flow can be summarised as below:
It is worth noting that the View can know about the availability of the data in the Model either through Controller -- also known as Passive MVC -- or by observing the data in the Model by registering observables to it, which is Active MVC.
On the implementation part, one of the first things that comes to mind is that what android component should be used for the View? Activity or Fragment ?
The answer is that it does not matter and both can be used. The View should be able to present the user interface (UI) on the device and respond to the user's interaction with the UI. Both Activity and Fragment provide the required methods for this.
In the example app used in this article I have used Activity for the View layer, but Fragment can also be used.
The complete sample app can be found in the 'mvc' branch of my GitHub repo here.
I have also dealt with the pros and cons of MVC architecture in android through an example here.
For those interested, I have started a series of articles on android app architecture here in which I compare the different architectures, i.e. MVC, MVP, MVVM, for android app development through a complete working app.
I think the most useful simplified explanation is here:
http://www.cs.otago.ac.nz/cosc346/labs/COSC346-lab2.2up.pdf
From everything else I've seen and read here, implementing all these things makes it harder and does not fit in well with other parts of android.
Having an activity implement other listeners is already the standard Android way. The most harmless way would be to add the Java Observer like the slides describe and group the onClick and other types of actions into functions that are still in the Activity.
The Android way is that the Activity does both. Fighting it doesn't really make extending or doing future coding any easier.
I agree with the 2nd post. It's sort of already implemented, just not the way people are used to. Whether or not it's in the same file or not, there is separation already. There is no need to create extra separation to make it fit other languages and OSes.
Being tired of the MVx disaster on Android I've recently made a tiny library that provides unidirectional data flow and is similar to the concept of MVC: https://github.com/zserge/anvil
Basically, you have a component (activity, fragment, and viewgroup). Inside you define the structure and style of the view layer. Also you define how data should be bound to the views. Finally, you can bind listeners in the same place.
Then, once your data is changed - the global "render()" method will be called, and your views will be smartly updated with the most recent data.
Here's an example of the component having everything inside for code compactness (of course Model and Controller can be easily separated). Here "count" is a model, view() method is a view, and "v -> count++" is a controller which listens to the button clicks and updates the model.
public MyView extends RenderableView {
public MyView(Context c) {
super(c);
}
private int count = 0;
public void view() {
frameLayout(() -> { // Define your view hierarchy
size(FILL, WRAP);
button(() -> {
textColor(Color.RED); // Define view style
text("Clicked " + count); // Bind data
onClick(v -> count++); // Bind listeners
});
});
}
With the separated model and controller it would look like:
button(() -> {
textColor(Color.RED);
text("Clicked " + mModel.getClickCount());
onClick(mController::onButtonClicked);
});
Here on each button click the number will be increased, then "render()" will be called, and button text will be updated.
The syntax becomes more pleasant if you use Kotlin: http://zserge.com/blog/anvil-kotlin.html. Also, there is alternative syntax for Java without lambdas.
The library itself is very lightweight, has no dependencies, uses no reflection, etc.
(Disclaimer: I'm the author of this library)
According to the explanation that the Xamarin team explained (on the iOS MVC "I know it seems weird, but wait a second"):
The model (data or application logic),
The view (user interface), and
The controller (code behind).
I can say this:
The model on Android is simply the parcelable object. The view is the XML layout, and the controller is the (activity + its fragment).
*This is just my opinion, not from any resource or a book.
There is not an implemented MVC architecture, but a set of libraries / examples exists to implement an MVP (model–view–presenter) architecture.
Please, check these links:
https://github.com/sockeqwe/mosby
https://github.com/android10/Android-CleanArchitecture
https://github.com/antoniolg/androidmvp
Google added an example of an Android architecture MVP:
https://github.com/googlesamples/android-architecture
I have seen that many people are saying MVC is already implemented in Android, but it's not true. Android follows no MVC by default.
Because i don't Google will ever forcefully impose the restrictions of an MVC implementation like iPhone, but its upto the developers which patteren or technique they want in their project, In small or simple applications use of MVC is not required, but as the application grows and get complicated and require modification's of its code in later years, then there comes a need of the MVC pattern in Android.
It provides an easy way to modify code and also helps in reduction of issues.
If you would like to implement MVC on Android, then follow this below given link and enjoy the MVC implementation in your project.
http://www.therealjoshua.com/2011/11/android-architecture-part-1-intro/
But nowadays i think MVP along with Android Architectural Pattern is one of the best option developers should use for a clean and robust android applications.
When we apply MVC, MVVM, or Presentation Model to an Android app, what we really want is to have a clear structured project and more importantly easier for unit tests.
At the moment, without a third-party framework, you usually have lots of code (like addXXListener(), findViewById(), etc.), 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 unnecessary 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.
In my understanding, the way Android handles the MVC pattern is like:
You have an Activity, which serves as the controller. You have a class which responsibility is to get the data - the model, and then you have the View class which is the view.
When talking about the view most people think only for its visual part defined in the xml. Let's not forget that the View also has a program part with its constructors, methods and etc, defined in the java class.