The final post in the Frustromantic Box series deals with the software side of things.
Monthly Archives: January 2010
The Frustromantic Box, Part 3: Electronics
In this series’ third post I describe the electronics involved in the Frustromantic Box.
The Frustromantic Box, Part 2: Assembly
The Frustromantic Box is my implementation of Mikal Hart’s Reverse Geocache Puzzle. In Part 1 of this series I gave an overview of the project and its parts list. This post describes how I cut the pieces and put them together.
Continue reading
The Frustromantic Box, Part 1: Intro
A few months ago, Hack A Day featured an ingenious hack called the Reverse Geocache Puzzle by a gentleman named Mikal Hart (please note that “Reverse Geocache Puzzle” is Mikal’s trademark – my unabashed clone of his project will hereafter be known as the Frustromantic Box). As soon as I saw it, I knew I had to build one. It took a lot longer than I thought it would, but I had the finished product ready in time for my wife’s Christmas present. She still hasn’t opened it, so I have to be a little cagey here.
I’ll describe this project in a series of posts. This post – the first – will go over the high-level design of the box.
Android Swingworker
I’ve been fooling around with the Android development platform. It’s quite an adjustment, coming from the iPhone world. I thought I’d post a simple equivalent to the SwingWorker class that works with Android’s Event Dispatch Thread. Here it is:
package ca.razorwire.util;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
public abstract class UIWorker
{
private static final ExecutorService __execSvc;
private static final Handler __edtHandler;
private static final String TAG = "UIWorker";
static
{
__execSvc = Executors.newSingleThreadExecutor();
__edtHandler = new Handler( Looper.getMainLooper() );
}
public abstract void doInBackground();
public void done()
{
// Log.d(TAG, "done() executing in thread " + Thread.currentThread().getName() );
// This space intentionally left blank
}
public void execute()
{
// Log.d(TAG, "execute() executing in thread " + Thread.currentThread().getName() );
final Runnable doneRunner = new Runnable()
{
public void run()
{
UIWorker.this.done();
}
};
final Runnable bgRunner = new Runnable()
{
public void run()
{
// Log.d(TAG, "bgRunner executing in thread " + Thread.currentThread().getName() );
UIWorker.this.doInBackground();
__edtHandler.post( doneRunner );
}
};
__execSvc.submit(bgRunner);
}
}
And here’s a sample usage:
UIWorker worker = new UIWorker()
{
public void doInBackground()
{
Log.d( TAG, "Sleeping for a bit." );
try { Thread.sleep( 10000 ); } catch ( Exception ignore ) {};
}
};
Log.d( TAG, "Executing worker..." );
worker.execute();
Log.d( TAG, "Returned from execute()" );
If you uncomment the Log calls in UIWorker, you should see some output like this:
07-08 12:14:11.015: DEBUG/rweeks(1078): Executing worker... 07-08 12:14:11.015: DEBUG/UIWorker(1078): execute() executing in threadmain 07-08 12:14:11.025: DEBUG/UIWorker(1078): bgRunner executing in thread pool-1-thread-1 07-08 12:14:11.035: DEBUG/rweeks(1078): Sleeping for a bit. 07-08 12:14:11.035: DEBUG/rweeks(1078): Returned from execute() 07-08 12:14:21.038: DEBUG/UIWorker(1078): done() executing in thread main
Public domain code, no guarantees, seems to work.