Event Driven Development

Callbacks Hooks Vapor Hook Framework Published : 04/03/2013

Writing event driven apps is particularly useful in applications that expect some form of user interaction, usually via touch interactions on the device screen.

For example, you want to define some asynchronous callback code for a button that only gets executed when the user presses that button. Since the time of that event cannot usually be determined beforehand we tie the code to the button in a callback.

Vapor API initially started out as just a framework for manipulating View components, but I realised that the wider objective was to make Android app development easier. A powerful part of that is callbacks, and thus the Vapor Hook Framework was born.

The VaporHookEngine itself utilises the Singleton Design Pattern. This buys us a single handle to the VHE that we can retrieve statically from anywhere in an application. It follows that we can then also manage and fire hooks from anywhere too, meaning you needn't keep alive a reference to a particular hook in your code.

This is really useful for dynamic subscribing and unsubscribing when certain conditions are met. For example, if I have a VaporActivity that's backed by a VaporService, I will call $.bind(ServiceClass.class) to create the service binding, and stick any code reliant on this binding being established inside the VaporActivity.SERVICE_BIND hook. I can then do the rest of the set up that relies on this binding inside the callback, and call $.hook(VaporActivity.SERVICE_BIND).hookOut(this) from inside the .call(String,VaporBundle) code - just before the callback method returns.

Speaking of hooking in and out, whilst developing the Vapor Hook Framework I stumbled upon the dreaded ConcurrentModificationException when modifying the underlying subscribers collection during that hook's callback. A few hours of tweaking later, and the inner guts of the VaporHook class hasd been reworked to allow you to arbitrarily hook in and out at your leisure in your code.

Moreover, I didn't want this concurrency privelege to come at the cost of synchronization overheads on the subscribers collection. Therefore the solution I came up with was to use a temporary shadow list, and some bespoke data structures to keep track of changes. The changes can then be merged back to the original subscribers collection afterwards.

This worked but was still a bit naive, and so to make this even leaner the shadow collection facility is only used when you attempt to modify the subscribers collection during a callback. If the hook is not in the process of firing there is no need for the shadow!

Vapor Hooks have lots of customisable functionality and behaviour so it's worth having a poke around - you can even set a hook up to automatically delete itself once the number of hookees reduces to 0. Also, if a hookee $subject reference has degenerated to a NullPointer the Vapor Hook Framework will automatically hook out this bad reference to avoid an exception. Having said that, you should be responsible for managing hook subscribers yourself as this is only a fallback measure.

The Android apps I write with Vapor API are full of event driven code, and I'm sure yours will be too once you've had the chance to play with the Vapor Hook Framework - another powerful feature built-in to Vapor API.

Until next time...