Recently, I have been working on a Model-View-Controller framework for Android. Have been having a crazy and interesting life since.
The infrastructure is something as follows:
- An Activity act as a “View”
- There’s a “Controller” – a singleton class – that keeps a track of all transactions across the “View” and the “Model”
- Business Entity representing the “Model”
- Then there is “Command” that represent any transaction / action triggered from the “View” to generate the “Updated Model” and result
- A “Command Manager” to keep a track of all business operations so that, just in case, a command needs to be terminated and/or for general bookkeeping
There are quite a few interesting challenges that I came across while working on the same… and continue to evolve it:
- Everything happens on the client side – there’s no browser that will take care of the “Back” and “Forward”
- Cannot rely on the OS default handling of the launching of the new activities and the hardware back button
- So as to provide a support for the Back button, because that’s the only one on the device by default, the controller has to keep its own stack of multiple items – activity, data used to launch and initialize the activity, any changes that may have happened in the state while interacting with the activity itself – the last of which I still need to do
- Most of the new activity launches are triggered from data transactions over network. For example, after the login screen, I jump to the home screen and upon performing an action (like click) on some item on the home screen, I navigate to, say my messages activity. As such, the controller has provided a support for “progress” – not just on the top of the activity but as a full-screen activity
- While going “Back”, the controller had to be made smart enough to ensure that the “Progress” activity is never shown but the real previous activity is launch with appropriate data for initialization
- The activities talk to the controller for a business operation to be performed on a piece of data (model). As such, you can say, the controller follows the front controller pattern. For those familiar with the Struts framework, controller is something similar to
ActionServletto which *.do or /do/* is mapped or like the
StrutsPrepareAndExecuteFilterin Struts2 that pre-processes all incoming requests
- Most of the business operations, as what I believe and least the case is in the current application that prompted me for creating the framework, will fetch data from either database or network. And in our case, we had no caching – any and all user interface when presented to the user will always get the latest data from the server. There’s no “Refresh” button. It’s always refreshed by default. And we would not like to block the UI thread while fetching the data. So, process all business operations in a non-UI thread and do a context switch just before the data is to be processed by the activity (the UI) – all that is the responsibility of the controller
- At some point in time, the “Back” button may need to be reset – saying that from the current point, no back is possible. Controller has the flexibility. Useful if the activity-stack gets larger or if the logic says, for example, on launching any activity from the options menu should reset the back-activity-stack
- It has to do all data housekeeping – what was the data used to launch the activity and initialize it. When to launch a new activity or when to update an existing one. Which activity to launch. Whether or not to terminate any previous business operations pending, for example, while navigating from one activity to another, any data communication to/from server may need termination… there’s a lot of hard work to be done by controller.
Well, this posting is just a primer for MVC for Android in terms of what are some of items to be taken care of.
I will create a project on SourceForge, publish the code there… and write the updates here.