Random thoughts, musings, and tech stuff

19 May 2014, 15:18

Share

Witness, a simple Android and Java Event Emitter

Source. I found this in an image search for ‘witness’. Had to use it. =)

I’ve been working on a project for Google Glass and Android that requires asynchronous messages to be passed around between threads. In the past, I’ve used Square’s Otto for this, but I wasn’t thrilled with the performance. Additionally, Otto makes some assumptions about which thread to run on, and how many threads to run with, that I wasn’t crazy about. Before continuing, I should point out that Otto is configurable, and some of these basic assumptions can be dealt with in the configs. Regardless, I felt like writing my own.

Code

Witness is a really simple event emitter for Java. The idea here is to build a really simple structure that can be used to implement observers easily. It’s sort of like JavaScript’s Event Emitter, and the code is short enough to read in its entirety.

I’ll start with Reporter because it’s so simple. Essentially, this is just an interface that you implement if you want your class to be able to receive events.

The Witness class maps class types to Reporter instances. This means that for a given data type, Witness will fan out the event to all registered Reporters. It uses an ExecutorService with a pool size of 10 threads to accomplish this as quickly as possible off of the main thread:

Usage

To receive events for a specific datatype, the receiving class needs to implement the Reporter
interface, then register for whatever data types the following way:

Update

It has the effect that events can be delivered on arbitrary threads. The event handler must be threadsafe, must synchronize access to shared or stateful resources, and be careful not to create deadlocks. Otoh if you use a single event queue, you avoid this kind of complexity in the first place. I’d opt for the latter, threadsafe programming is something you want to avoid if you can.﻿

I should note that my usage is all on Android, where I’m explicitly specifying the thread that the events will run on using Handlers. I haven’t used this in a non-Android environment, and I’m not entirely sure how to implement the equivalent behavior for regular Java.