For the past few months I have been working on an Android application that collects automotive CAN bus data – ultimately for analysis with BigData technologies such as Hadoop. I have already described some aspects of this project here and here. Thus far close to 2 Terabytes of data has been already collected.
In this post I would like to recount my experience of using F# with Xamarin for a real-world mobile application.
Before anything else, I want to state that this was a substantial effort and the final app has over 6000 lines of new F# code. It is by no means a toy app. It is a complex app with several system and user interface points and non-trivial background processing. It is meant to run for several months without any involvement by the user – after the initial setup.
Here is a partial list of app features / highlights, roughly in decreasing order of complexity:
- Bluetooth and USB interfaces to the OpenXC dongle
- About 10 Android screens with two custom built graphical controls
- ProtoBuf protocol for higher throughput data transfer over Bluetooth
- Asymmetric and symmetric cryptography
- Compression of data before upload
- OAuth authentication via Azure Access Control Service
- Upload to Azure storage via a WebAPI
- A settings/preferences module where the UI is auto generated (partially portable to IOS)
- Android features: Service, Alarms, Notifications, BroadcastReceivers, Toasts, Intents, PendingIntents, Activities, Dialogs, etc.
- Pervasive use of F# Actors and async computations (events bus, pub-sub, ‘nanoservices’)
Under the stress test framework, the app can happily run all day long processing around 7000 msgs/sec over Bluetooth on a Samsung Galaxy SIII (10,000+ msgs/sec rate is achieved if messages are not stored). The package size is about 8 MB and the runtime size is between 25-50 MB.
Xamarin F# support is now very good and I will gladly recommend that for production use. When I started out, F# support was still in beta and I ran into many issues. However the Xamarin team was super responsive and have rapidly advanced the plug-in to where it is it now stable and very usable.
Just a few points to note if you want delve into F# and Xamarin. You need to install both F# 2.0 and 3.1 runtimes before F# will work.
I ended up writing our own simple Actor (MailboxProcessor) implementation which gives us better memory performance at the cost of smoothness (in distribution of processing) than what we get from native F# MailboxProcessors. This implementation can be found here: http://fssnip.net/m8
We had most issues with Bluetooth connectivity. Once that part was sorted out it was relatively smooth sailing. I had to learn Android programming from scratch – a big learning curve. We still have Bluetooth issue with older Android phones but it is something that we have no control over. We did run into the Android fragmentation problem and so had to test the app on a wide variety of devices to resolve all of the issues. The app runs well on all new phones and most old (Android 2.x) phones.
With so much processing happening, battery consumption is an issue and the app consumes anywhere from 15% to 30% of the battery for a typical day. This means that users have to charge their phones everyday.
All-in-all it was a great (but humbling) experience. I have new respect for mobile developers. F# and Xamarin triumphed. I can’t imagine writing such a complex mobile app in another language. Instead of 6K, equivalent Java code would be in the 50K LOC range and of untenable complexity. I think F# is a great language for mobile computing. It is surprising how much you can do on these devices today.
Updated: Also see this InfoQ article for additional references.