Implementing IPC on Android™? The Message class allows you to pass data from one thread (or AsyncTask) to another within your app (like that pesky UI thread!). It’s all helped out by Bundle and passed through a Handler.

The Message + Handler architecture is all reasonably well-documented by Google and elsewhere. But what if you want to pass a nice, rich POJO of a complex class, nicely populated with data so it will be ready to use in the other thread? Of course you can use the raw capabilities of the Bundle to stuff Strings and primitives in a map of sorts, but that’s awfully tedious if you’ll be passing a big class around. You can pollute your POJO class with the Parcelable interface… no thanks.

This is just a little note about avoiding the cumbersome Parcelable interface and making life easy with Jackson and JSON-serialization instead. It’s not intended to be a general tutorial on IPC in Android.

Valarm’s OBD2 driver and Bluetooth handling run in an AsyncTask, but they obviously interact with the UI and other threads (e.g. Toast messages, handing alarms off to the storage and web-posting threads, etc). When an internal AlarmEvent is created by any of the OBD2 sensors, we’d like to pass that rich object over to the background service which will dispatch it to the various handlers (Valarm sends out SMS messages, pops up a Toast, posts JSON to the webservices, and even plays back alarm sounds).

Here’s the code down in the OBD2 driver that passes along an AlarmEvent:

private final Handler uiMessageHandler;

public void triggerAlert(AlarmEvent alarmEvent) {
    try {
	final byte[] event = 
            BackgroundService.JACKSON_MAPPER.writeValueAsBytes(alarmEvent);
        final Message msg = 
            uiMessageHandler.obtainMessage(BackgroundService.MSG_WHAT_ALARM_EVENT);
        final Bundle bundle = new Bundle();
        bundle.putByteArray(BackgroundService.MSG_KEY_ALERT, event);
        msg.setData(bundle);
        uiMessageHandler.sendMessage(msg);
    }
    catch(Exception e) {
        Log.e(LOG, "marshalling AlarmEvent...", e);
    }
}

Where’s the magic that actually makes this blog entry worthwhile? It’s the BackgroundService.JACKSON_MAPPER.writeValueAsBytes(…) That JACKSON_MAPPER is a public static final instance of ObjectMapper, a central part of the most useful, well-written, well-documented libraries I’ve used in a long time. Valarm uses Jackson on the Android as well as on the webservers to process JSON of all sorts. And it is FAST. And EASY to learn and use.

Here’s the other side of our little IPC message pipeline, which receives the message and dispatches it as necessary:

public static final String MSG_KEY_ALERT = "msgKeyAlert";
public static final int MSG_WHAT_TOAST = 77; // anything unique amongst its peers
public static final int MSG_WHAT_ALARM_EVENT = 88; // see comment above
public static final ObjectMapper JACKSON_MAPPER = new ObjectMapper();

private Handler sensorMsgHandler;

public BackgroundService() {
    ... snip ...

    sensorMsgHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_WHAT_TOAST:
                    Toast.makeText(
                        getApplicationContext(), 
                        msg.getData().getString(MSG_KEY_TOAST), 
                        Toast.LENGTH_LONG)
                    .show();
                    break;                
    	        case MSG_WHAT_ALARM_EVENT:    	        
    	            try {
                        // YAY, wonderful, convenient and speedy unmarshalling by Jackson!
    		        final AlarmEvent alert = 
                            JACKSON_MAPPER.readValue(msg.getData()
                                .getByteArray(MSG_KEY_ALERT), 
                            AlarmEvent.class);
    		        triggerAlert(alert); // pass it along to our AlarmEvent pipeline
    	            }
    	            catch(Exception e) {
    	                Log.e(LOG, "unmarshalling AlarmEvent...", e);
    	            }
    	            break;
    	        }
            }
    	 };    	
    }

    ... snip...
}

Jackson is now our go-to JSON library here at Valarm. With the amount of JSON we pass around: from the devices up to the webservices, and from the website down to the JavaScript in our web interfaces, we’re constantly moving JSON around. I can hardly stand to think of life before Jackson: with the straightforward & sturdy, but slow, tedious, and unhelpful org.json library… yuck!

 

Have a gander at our Industrial IoT Customer Success Stories to see how our customers use our Tools.Valarm.net web services to save time, money, and lives by monitoring water and other valuable assets.