Monday, November 4, 2013

Decoupling your Android code

Android as a platform offers a lot of different components to be used around. In a single Activity you might find yourself with a stack of Fragments, Views, Model data, adapters, Action bar actions, View actions (click), context menus and more.
Aiming to combine them all in an elegant way that will guarantee you with flexible and modular code will require you to “decouple” them from each other. That way, you will have the opportunity to re-use them, and make future changes easier.

Before using the tools up ahead,
ask yourself: How far should the decoupling go?
Making every part of the application “loose” and replaceable will eventually make your code less-readable and you’ll miss the point. Not everything is meant to be used or reused across the app and different apps. Trust me on this - don’t over do it!

Event Driven

Lets face it. Building an Android, as a client side application, requires us to work mostly in an Event-Response model, or “event driven”. Most actions are happening because something has happened - for example: Tap on a button, network request finished, battery is low, the OS is terminating us, etc.
What tools are you using to help you implement these event-response model?

Tools for decoupling

Here’s a selection of tools you can use, from basic to the advanced:
  • Java language - using interfaces, anonymous classes and such for delegating around the “callback” for your event.
    You will find yourself creating a lot of interfaces, methods for ‘setOnSomethingListener’ methods, checking that the callback is not null, firing the event. And don’t forget to unregister the callback otherwise you might find yourself leaking memory. Not much fun ha?
  • LocalBroadcastReceiver - Passing messages using Android SDK.

    First, don’t confuse the basic BroadcastReceiver with the *Local*BroadcastReceiver. The later one is “Slimmer” then the regular BroadcastReceiver because it sends the message inside the process and not through the OS’s IPC . Assuming that you intend your messages to be delivered inside the app, and to avoid some security breaches (no one can instantiate your LocalBroadcastReceiver…) - USE THE LOCAL.
    While this solution is nice and saves some code, it still doesn’t feel fit to use it for simple operations. The register and firing of event is a bit of a hassle. You will still need to define the “contract” between the listener and the invoker. Still need to unregister to avoid leaks, and such…
  • 3rd party, Event bus - Passing messages. The easy way.

    There are currently two major libraries offering decouple your code in a more elegant way. These are:
    • Otto - The old solution, allowing good code base from the creators of Square. This offers a straight forward implementation, with the use of java annotations. Example from their website:
      • Create it: Bus bus = new Bus();
      • Register for events: bus.register(this);
      • Respond to events:
        @Subscribe public void answerAvailable(MyEvent event)
        { // TODO: React to the event somehow!}
      • Post event: bus.post(new MyEvent("smtn"));
    • Green robot Event Bus - A newer solution, aiming to deal better with Threading and general speed performance. Some open issues might needs to be considered before selecting this solution. This offers a implementation with a naming convention instead of the use of annotations.
    While Green robot is displaying a better benchmark of performance and other features in comparison to Otto, My personal choice is still Otto because usually I don’t use the extra benefits of the threading, and they simply feel more solid for this crucial task.
What’s your take on decoupling practice? Write a comment!

No comments:

Post a Comment