I'm starting Android app development and just after my very first app more complex than Hello World I found out that you cannot hold any state in Activity because Android will recreate them in some cases... ouch, failure.
I'm guessing that strict model separation from view is a common practice, even for simple apps. Are there any settled patters I should follow? Some variant of Model-View-Controller?
You should definitely read the Application Fundamentals Dev Guide
In my experience, my design patterns in Android have been driven by the use of Intents, Activities, Services, Broadcast receivers and so forth.
I wouldn't say that "strict model separation from view is a common practice". You can keep data inside an Activity, but you will be forced to preserve it. Luckily this is made trivial by methods like onSaveInstanceState and onRestoreInstanceState where persistent data members can be saved to a Bundle and then retrieved from the same Bundle.
Related
I am and android developer and I have worked on all of these three architecture patterns in my applications. Also I have gone through several post's on stackoverflow about the difference of each. My understanding might not be 100% correct but this is what I know so far in brief.
MVC - User input is received by controller. Controller updates the model then tells the view to update itself.
MVP - View gets the user input and notify the Presenter. Presenter gets the data from Model and then sends it to View. Presenter and View have one-to-one relation.
MVVM - User input is received by View. ViewModel generates the data from Model and puts out a stream of data any View subscribed to it can consume that data. View and ViewModel have one-to-many relation.
The problem is that many times in interviews I have been asked the question to tell which pattern to use when. What I think the interviewer wants to know is the type of application (like banking, e-commerce, etc) and their appropriate architecture pattern. Or at least some concrete explanation as to why I would like to use MCV in one application and MVP in another and so for MVVM.
I did my research well but could not found any proper answer on the internet that talks about the use case of each pattern. Thus, request to please tell me use case for each.
From my knowledge:
MVC: Model View Controller is the traditional old way of Android development. This was used when Android development just started and was avidly used for few years. In this time, the only well known pattern was MVC.
So, mostly all old applications started as MVC but as the code base increases, the controller(Activities/Fragments) become bulky with lot of business logic and network requests and async tasks living in them. So, such applications become difficult to maintain overtime and are very harder to test due to the high dependency between the three.
So, if your application is very small and you want to follow no new architecture patterns or have 0 understanding of those use MVC but I highly recommend not to follow MVC in this time.
MVP -> As MVC applications become difficult to maintain and test, applications transitioned towards MVP.
Model View Presenter tried to resolve the problems of MVC and moved presentation and business logic to presenters. The presenter here just performs the Interface actions and has no knowledge of the Views it is trying to update. So, as presenters are not similar to controllers we can easily test presenters and models. So, we achieve testing and maintenance benefits but it also creates a problem that now presenters are the smart one. They start becoming bulky eventually. Creating a similar problem.
Also in android, apps need to maintain app state. MVC and MVP don't come out of the box to have state saving capabilities, you need to write additional code for state maintenance.
MVVM on the other hand is most popular. Model view viewModel is the new android architecture.
You can go in detail and learn this:
https://developer.android.com/jetpack/docs/guide
Network connections live in repository. So, code is much cleaner in your fragments or activities. All three components are easily tested and maintainable.
One of the biggest advantages is you have performance benefits as it does the state saving mechanism out of the box as ViewModel follows the singleton pattern and you can achieve that by using ViewProviders and creating instance through it.
When you say what application should use what. If an application size is huge and complex would highly suggest MVVM and you can also look into other popular architecture components like MVI and clean architecture(Use case based) as well. In my opinion, an application product type doesn't change architecture requirements. It's the complexity and size that determines it. Your security requirements change based on the product.
I am thinking about using mvvmcross in one of the projects. For now I am just exploring the mvvmcross and going through different articles, but I cannot find anything relating to mvvmcross and android service. How to start, stop or bind to service in view-model. What is the "best" approach when dealing with services? Does anybody has a link or anything on the subject.
Uros
In general I treat Android services, ios long running tasks and Windows background tasks as separate 'services' and they don't generally interact directly with the ViewModels, but instead interact via messaging, via data stores, etc. Specifically for Android, you may need to use View/Activity level hooks like service local binding (see Android - Service and Activity interaction)
When the background services share the same process (same memory space) as the ViewModels, then one thing that can seem a little awkward is initialising shared IoC and any required application singletons. However, generally this doesn't seem to be too hard to do - e.g. see questions like Using MvvmCross from content providers and activities and MvvmCross initialization
I haven't personally seen enough examples of this type of app to work out if there's a few common architectural patterns that could be supplied at an mvvm-platform level. I'd love to see more examples and more people talking about architectural ideas in this area.
I’m not an Android pro though I’ve developed an app consisting of more than 50 activities which makes the app really large. After 8 weeks of developing, now there are problems which caused the app difficult to maintain and upgrade.
Major ones I’m dealing with are
I cannot pass object reference to activities’ constructors. In fact I found the mechanisms of startActivityForResult – Intent – onActivityResult really limiting and results in dirty code of many constants for actions per activity and a lot of switch case that is really hard to follow the flow of app.
Another problem is that I do not know how to manage the life cycle of the whole app as each activity has its own life cycle.
I had some successful experience with LWUIT and J2ME – polish which ignore J2ME MIDlets (similar to android activity) and implement their own architecture and windowing system with just one MIDlet as entry to the app. I’ve come up with the same idea for android.
To clarify, I’m thinking of an app with just one main Activity and other activities implemented as objects which extend View object and these views can be dynamically added to main activity FrameLayout and stack on each other. Activities’ logic can be implemented in such classes and I've even found a way to implement dialogs in this way.
Business and state objects can be passed to their constructor and it sounds good ignoring its side effect of writing a little more code. This way listeners can also be passed to views’ constructors which makes app UI switch and flow management easier.
But the questions are:
Is it a good practice?
Wouldn't it lead me to performance or memory issues?
I'm also aware of
Android: What is better - multiple activities or switching views manually?
Don't Overload a Single Activity Screen
Pattern one activity, multiple views. Advantages and disadvantages
None of these clearly address the issues regarding performance or practice with reasonable evidence or documented reference
Please someone help me with this
There are popular apps in market with only one or a few activities. They use fragments and switch them. I would prefer fragments over your approach. Although I think fragments are too complex for many purposes, for your use case it would be a good solution. Your UI behavior should be in fragments, and your activity is the controller part transferring data between your fragments. Fragments also have an own life cycle.
I don't like startActivityForResult either. If I have a set of activities - all providing data - and I don't know in which order they will be called, I prefer to use a singleton class then using intents for data transmission between activities. But you have to analyze your problem to get a good solution.
There is already an MVC framework built, PureMVC library.
I've been coding for my Android phone lately, and i've been wondering... is this Intent class supposed to outline a new programming style?
I've been suspecting the API design discourages MVC: Intents are the main way to interact with all user-related objects (Activities, Services, Other apps...).
Is my train of thought right? Should is stick to "contaminating" Activities with business logic?
I have been reading the android developers site and no particular coding style is encouraged though.
Your question isn't entirely clear, because you seem to be confusing coding style with program architecture.
In my mind, Android really changes nothing in terms of coding style. Your coding style from Java will still work fine, and most Android apps look very similar to other apps. In the abstract, there are some things that you might want to do in Android you don't do as much in other languages, see the Android guide for details. The basic idea is: memory is limited, don't use it if you don't have to.
As far as whole program architecture goes, yes, the Android style is highly based around the message passing (through Intent objects) style. The way you react to GUI events within an Activity is still largely the same: you use event handlers to react to events like button presses, etc... But the platform is strongly centered around designing apps using different components (Activities, Services, BroadcastReceivers, etc...) and Intents to communicate between them. While Intents provide a flexible way of exchanging data between components, you still shouldn't be passing massive amounts of data within Intents, instead you should put those kinds of things in a ContentProvider or something similar.
I took a lot of the following ideas I took from this OReilly book. This is just whats worked best for me.
As far as architecture goes, its helped me to think of Android's UI as a Page Controller pattern - I found it to be similar to .Net Web Forms actually. So yes, it does fit with MVC (at least the Page Controller flavor of it). An Activity is your controller, you typically store your view in XML, and you can build out your Model however you like.
You see a lot of web-ish ideas in Android. Intents are a lot like HTTP, or more generally REST. Intents have a 'noun' that says what they are concerned with (can be explicit class declaration ie: go to a specific Activity, or can be more implicit using Intent Filters), the Action is a lot like an HTTP verb (Get, Post, etc), a Bundle is a lot like a list of query string parameters or payload...etc.
And similar to a web page, you want an Activity to be able to take care of itself. What I mean is, you don't want to pass around some big serialized object from activity to activity, its a lot cleaner/resilient/reliable to just pass the id of the a given record to the next Activity and let that activity grab the record with that id from the db (ContentProvider, some other persistent source...). Activities are also meant to be loosely coupled, and you're supposed to be able to navigate to one from various paths, it also makes them more re-usable. Thus, allowing the callers of an Activity to simply provide a recordId is a lot easier then the Activity expecting its consumer to have provided a large serialized object.
Bottom line - no, you don't need to contaminate Activities with Business Logic, tuck that stuff away in an application layer, or a gateway or something like that. As for persistence, the ContentProvider interface is pretty well designed - I like it alot. It also continues the Android RESTful theme, accessing content via URLs and verbs (query, delete, update, insert).
Sending and receiving intends is much like sending and registering (similar to a publish-subscribe channel) for command messages (e.g. in a distributed enterprise application, and this is about architecture, not style). This pattern helps designing a loosely coupled system of interacting applications.
I cannot remember having seen a similar architecture before used for the interaction of components and applications on a single computer but it helps to design application using other applications to easily build an ecosystem of features/components.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I was a JaveEE developer. Recently I joined an Android development team. The structure of Android confused me. The MVC design pattern doesn't seem to suit for Android development. So what is the design pattern principle for Android development? I mean is there any hint about how to write a clean, easy reading and effective Android code.
Android's architecture annoyed me at first, but I beginning to see a method to their madness. It's poorly explained by the android documentation. My biggest gripe has always been that it's hard to have a centralized data model with objects that your Activities share just like a normal application. Android seemed to want me to be a nomad because I could only share primitives between my Activities. And dropping junk in a database is NOT a model because it contains no behavior. So as most people my business logic all ends up in my activity making it hard to share business logic in other activities.
I've come to find out I was missing some key puzzle pieces. Android is MVC. However, it's coupled to the View fairly heavily.
Activity == Controller
Model == Subclass of Application
Anything that subclasses View == View
Interestingly you can create a subclass of Application and declare this in your Manifest file, and Android will create a single instance of this object that lives the length of your application no matter what Activity is destroyed or created. That means you can build a centralized data model there that all Activities have access to.
The way I see this is something like a primitive Spring container that you can initialize objects and resolve dependencies between them. That way you can decouple the model portion of your application away from the Activity themselves. And just have the Activity make calls on the model, and hand callbacks to receive the results so it can update the UI.
The problems with Android is that it mixes controller and view pretty heavily. For example, subclasses like TabActivity, ListActivity imply a certain view being used. So swapping out a view is pretty involved. Also the Controller makes very specific assumptions about what the view is even if you use Activity. He contains direct references to UI objects like TextView, etc. And it registers for low level events like clicks, keyboard, etc.
It would be better if Activity could register for more high level events like "Login", "Update Account Balance", etc which the view would dispatch in response to a series of clicks, keyboard, touch events. That way the controller works at the level you might describe features instead of design features.
I think we'll reach this type of design eventually as we better understand come up with better tools and techniques. It seems like Android might have the extensibility to make this happen, but it's up to community to chart it.
The actions, views and activies in Android are the baked in way of working with the Android UI and are an implementation of a model-view-viewmodel pattern, which is structurally similar (in the same family as) model view controller.
To the best of my knoweledge, 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.
You can find MVC in the followings:
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 store data in SQLite or your custom data in /assets/ folder, read more about resources and assets
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 model, and have your own packages, that will act as a structure
A lot of Utils have been already written for you. DatabaseUtils, Html,
There is no single MVC Pattern you could obey to. MVC just states more or less that you shouldn't 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 activites 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 this things in your code, then you're anyway following a MVC pattern.
Android development is primarily GUI development, which like Swing/AWT in Java consists of lots of anonymous inner classes reacting to GUI events. Its one of the things that has really kept me away from doing a lot with Swing....but I have an Android phone, so I'm going to grit my teeth and just get over it, as many an Apple fanboy has said about the antenna problems. ;)
Android makes the typical decision of making the Controller and the View a single class. This encourages putting too much in the same place. An Activity corresponds to a screen, each View to a region of a screen (sometimes the whole screen), each Controller to the user gestures from that region of the screen, and Models are just Models, sometimes backed by services from Environment or some other crazy little set of utility functions. I use the Activity to coordinate one or more MVC trios. This helps deal with Android's choice to just throw everything in the same place.
I can test the vast majority of an Android app without running the simulator. Big win.
Sorry for my English.
Android has a very good modularity (Activities, Fragments, Views, Services, etc.). So there is no need in MVC.
Of course there is the separation of taking input (Activities, Fragments), logic, view (xml or java) and data (databases, files, preferences). But this is not MVC. You shouldn't try to use MVC, it will only complicate your architecture.
Rather than keeping something in global scope, Android motivates you to keep objects as deep as possible in their scopes (class members, local variables), and pass objects to/from activities, or to fragments, using Intents/Bundles. This is also because of memory limitation.
The system may destroy your activity if the foreground activity
requires more resources so the system must shut down background
processes to recover memory.
So it's not safe to store not-constant (mutable) objects as global (static) objects. Usually you use static for immutable constants.
In simple terms, you separate your application into screens (Activities). Then each screen - into fragments (Fragments). To perform a sequence of actions on the screen you can also separate them using Fragments (example).
So you have very small blocks in your application, each of which you can easily test and reuse.
My impression is that android programming model has lots of similarity with MS WPF.
XML layout definitions, code that is always bound to one of these definitions...
So, if you are asking about design patterns because you want to improve your current or in development android projects, maybe you should look at WPF practices and patterns for improved architecture, like MVVM.
Check out these links:
http://msdn.microsoft.com/en-us/magazine/dd419663.aspx
there is small project that is already trying similar thing:
http://code.google.com/p/android-binding/
cheers