As I’ve already mentioned last weekend I took part in AngelHack and took the opportunity to learn how to develop for an Android device (in this case a Kindle Fire) using C# and Xamarin Studio. The experience was a bit mixed, overall I think the folks at Xamarin have done a good job in smoothing the experience when targeting mobile devices, but there’s still a few rough edges. Here’s a run though of what I thought:
The installer for Xamarin Studio works well and does a good job of downloading and installing the large number of different components need to develop for various devices. However, it’s slow, not so much the download which came down surprisingly quickly but the installation took ages with the window’s installer promising “6 seconds remaining” but in reality I was still waiting minutes later.
Once I was past the installer I downloaded the tasky sample and tried to open in Visual Studio but all the projects refused to load. I tried both with VS2012 and the “Shell” version of VS2010. I think this is because I’d installed the Indie version of Xamarin Studio, which doesn’t have Visual Studio integration, so in this case my fault, but one might have reasonable expected a clearer error message about why the projects weren’t loading. This is especially true as the Visual Studio 2010 shell seems to have been installed by the Xamarin Studio installer (at least I have no memory of trying to install VS2010 shell on this machine).
Once I open the tasky project files in Xamarin Studio things started looking up. I soon got tasky compiling and working the emulator. However by default the Android emulator is setup to emulate a phone and I wanted to target a Kindle Fire, there are various other configurations of the emulator but none of them appropriate for Kindle development. Amazon has detailed instructions about how to setup your development environment to target kindle fire, however there only for folks using eclipse. Xamarin Studio installs the same set of tools described in the article but there installed under C:\Users\<username>\AppData\Local\Android\android-sdk in Windows, so it took me a while to figure out where they were (C:\Users\<username>\AppData\Local seems an odd place to install them to).
UPDATE: I’ve just installed XamarinStudio on another box and I noticed the installer asks you were you want to put the Android SDK, obviously this didn’t strike me as important information at the time and I just did “next > next > next”.
Once you’ve found the tools, you need to use the “SDK Manager.exe” to installing the following extra bits for Kindle Fire development (you’ll need to add a reference to “http://kindle-sdk.s3.amazonaws.com/addon.xml” under “Tools > Manage Add-on Sites … > User Defined Sites” before they are available). Then install:
- “Kindle Fire Device Definitions”
- “Kindle Fire USB Driver” (this doesn’t really install the driver it just downloads it, you then need to find the exe and double click it)
- “Intel x86 Emulator Accelerator (HAXM)” (again doesn’t install automatically, you need to double click the exe, and it wasn’t supported by my processor, but well worth doing if your processor does support it)
Before I had installed all of this a I tried “side loading” (directly dragging and dropping my compiled .apk via a USB connection) on to a kindle I’d borrowed. This didn’t work and the app just closed without display an error message. I strongly suspect that this was because I hadn’t uncheck the “Use shared runtime” option, but I haven’t tried “side loading” since. After I installed the “Kindle Fire USB Driver” I just let Xamarin Studio handle the deployment and it just worked.
Working with the Android emulator is slow and the emulator is a little crashy. The emulator seems especially prone to crashing after sleeping/unsleeping my laptop by closing/opening the lid. Although my laptop doesn’t support the “HAXM” accelerator checking the the “Use Host GPU” under the “AVD Options” ( AVD is Android Virtual Device) did seem to speed things up a lot. Starting the emulator and deploying to it is the slowest bit. There is a “Quick deploy” option which is check by default but that just produced strange error messages for me and after a bit of googling the suggested fix seemed to be “if it ain’t working turn it off”. Unchecking the “Use shared runtime” also slows things enormously, so make sure it’s checked during development. I had one other problem with the emulator which turned out to be a user error. When I first use the emulator it would go straight to the start screen of the app. Later, for reason I don’t understand, it started to show the lock screen of the Android OS, along with a “50% Loaded” message. I wasted a lot of time waiting of the “50% Loaded” to disappear, but after several restarts I realized the “50% Loaded” message was a red herring the emulator was fully loaded, I just need to unlock it by dragging the flashy circle over the lock sign.
Another problem that gave me a slow start to my development was that although the tasky project worked fine on both really hardware and the emulator I couldn’t for the life of me get a project I’d created via “File” > “New Project” to loaded into the emulator (I never bothered trying real hardware). When I tried to deploy, the app would seem to deploy but then exit straight away, I tried putting a break point in the first screen, it was never hit. I’m not sure what the problem was, I noticed the app didn’t have a manifest so I tried creating one, but it didn’t seem to make any difference. In the end I just gave up and used a copy of the tasky project to create my app.
The final glitch was related to libraries. I wanted to parse some JSON, easy right? As it turns out a bit of a struggle. I wanted to use newtonsoft.json.dll to do the job, but it you can’t use any old .NET binary to target an Android app, if the binary hasn’t been build specifically for Mono/Android you end up with weird error messages about object being from the wrong mscorlib.dll. I looked around for a version of newtonsoft.json.dll that targeted Android, but only found some old source, no binaries. Next I tried to use “system.runtime.serialization.json.datacontractjsonserializer” but this isn’t included in the Android libs. The one that I found that actually did the job was “ServiceStack.Text”, it’s true that service stack doesn’t provide binaries for Android, but it does at least supply a csproj in the main repo to build the source to target Android, so a big thanks to Demis Bellot for providing this.
Despite the problems I’ve laid out here overall I was very pleased with the experience of using Xamarin studio to target Android and now I have some Android hardware I may go on to build some apps. It’s true that I did encounter a lot of problems, but I hope to create bug reports and help get these solved. I didn’t add F# into the mix this time around, but I shall definitely be trying it out when it comes to building my next app.