Here at touchlab we’ve been deep underground building some really awesome products. This is great for business, but its put on hold some of our open source release aspirations. We have a couple open source projects in the works, but since both need some polish before they can see the light of day, and since we have limited time and resources, I thought I’d post a little about both and see if we get any requests to speed one or the other along.
HTML Selection – On iOS, you can override the selection process and provide the user with custom operations for the selected text. On Android, not so much. There’s no (documented) way to override what happens when the user completes a selection. Worse, the selection process is totally different on 2.2, 2.3, Honeycomb, and ICS. We rarely consider Android versions 2.1 and below, but it doesn’t get any better when you go in that direction.
For standard web page text, this works very well at this point. It needs a little extra work and documentation to prepare it for public consumption, but if its what you need, this thing will save you tons on time.
Superbus – On several projects, we needed the ability to submit updates to the server process, and they needed to persist and process in the background. In modeling this on multiple projects, we’ve found some common features that any background processing bus needs available. Superbus (name suggestions welcomed) provides the basic functionality required. Its an abstract Service class that manages a queue of Command objects. Command objects are also an abstract class that represents a discrete unit of work.
The Service has several callback methods that you should implement, centered around storage of commands. Android apps can be stopped and started by the system pretty much at will, so if you want to ensure your commands eventually get processed, you need to persist them.
You would implement:
addCommandToStorage(Command command) removeCommandFromStorage(Command command, boolean commandProcessedOK) loadCommandsOnStartup(List\<Command\> commands)
The most obvious storage solution is SQLite, but you can also easily use a file store. One of our projects really doesn’t need storage, so those methods are left empty. Also, if some of your commands need to be store, but some can be dropped (say a data refresh command), you can provide different Command implementations and only store the important ones.
Commands can be give a priority value as well, so if you want Commands to jump to the front of the queue, or run as delayed as possible, provide corresponding priority values.
What would remote syncing be without error handling? The Command object can throw either a TransientException or PermanentException:
void callCommand(Context context)throws TransientException, PermanentException
Transient exceptions are “soft” issues. Losing your network connection is a transient exception. If you believe the solution is environmental and will resolve itself, throw a TransientException. Permanent exceptions should be obvious. You’ve had a system problem, and its probably not going to sort itself out. SqlException, null pointer, etc. Your business logic has had a problem (expected problems or not), and you can’t continue.
Transient exceptions get put back into the queue, and the queue gets shut down for a little bit. The assumption is 99% of the time, a “TransientException” was caused by loss of network.
Permanent exceptions cause the command to be removed from the queue. You’ll need to deal with this in the callbacks and either report the issue to the user, or reset state in some way (or whatever, its your app).
Discussed additions are:
Parallel commands. Mark a command as parallel, and it’ll be processed at the same time as others.
Swimlanes. Name the swimlane the command should process in. Some times you need to maintain certain command order, but on independent lines. For example, remote sync writes, and data refresh reads.
Delayed write queue. If your front end has many data reads, you’d want to delay your data writes as long as possible. Put a write operation on the queue, and wait for a specified period of time. Every following request that comes in resets the delay. When all’s quiet, the delayed command processes.
Superbus is probably closer to done, but if you have a strong need for either today, get in touch.