At my workplace, HCHB, we are rewriting our product for Android since windows mobile 6.5 is pretty much dead and even finding hardware is becoming an increasingly difficult task. So 8 months ago we jumped into the world of java, android and eclipse. The shift from c++ to java has been nothing but smiles and unicorns. We will have a 1/3 less code. Plus the code is properly layered and more readable, but that is mainly from the benefits of starting with a good framework and not coding things in the ui layer like the winmo product is.
That being said I have some thoughts on android programming concepts.
XML layout is pure win
This is awesome, and a very powerful tool once you get the hang of it. Granted the eclipse plugin to view your layout is useless but its easy enough to look at a layout on the device. The whole R resource thing is mostly great, though when you have something like 200 screens it is cumbersome and you have to practice good naming convention.
Intents are great for small apps, killer (in a bad way) for large ones
If you are not familiar with the android way, when you enter a new screen information is passed along via intents and when you exit it can be passed back via intents. The same concept is also used when you rotate the screen. This means the UI really drives the creation and destruction of the business logic and you generally have to keep the cached object in the intent or in your sqlite instances.
For most small apps this works great, for ours, we chose a different road
The Long Road – The path we took
Our product has to maintain backward compatibility with the winmo code at a database layer so we couldn’t easily use sqlite to store state, and it needed to behave semi-close to winmo to make coding quicker. Also we have grandiose plans to implement this on other platforms that may never happen. Plus we didn’t really like the way the stock android handles everything so…
Everything hangs off the Application
The application is a built in singleton for every android application, we subclass this and all of our business logic hangs off of this application object in some form of another. How does this all work? Whenever a parent kicks off a child screen, we create what we call presenter objects which determine the flow of business logic to the actual screen. We put the hash code of the child presenter into the child views intent, the child presenter is then thrown into a list. Once the child view is created it grabs the hash code out of the intent, looks it up in the global list and then marries itself to the presenter via interfaces.
Presenter and View Marriage
This way we keep the presenter/business logic separate from the ui. We can also better support different screens, for instance on a Droid we generally show a list, then tapping on a item takes you to a details screen. So we have a presenter that handles phone type devices with a business object handling validation, moving the data to and from the database etc. On a tablet though we might want to integrate the list and details onto the same screen. So we just right a new presenter that uses the same underlying business objects as the first.
Once the child view is closed we pass the child presenter to the parent presenter in a child finished method, then divorce the two so garbage collection can take place.
What does this all buy us?
- We get well seperated logic, the Views handle their internal state. Controls keep track of themselves and redraw on views.
- In our case the business logic is actually on a different thread so we can do long running queries without adversely impacting the gui.
- We can theoretically support multiple platforms.
- The application is pretty easy to unit test and we try to write it in a way that makes it easy. Though we do not unit test every corner we generally unit test the tough stuff, crosses fingers will unit test the other things when we get the time.