If you follow me on Twitter (or the #monodroid hashtag), you might have seen some posts from me lately about progress on my new Android app, C# To Go. I’ve been cranking away on it in hopes of getting it to market in time for Monospace, and I’m excited to say that last night I was able to finally publish it! I just wanted to do a quick write-up about the app, what it can do and how it was made.
First off, C# To Go is exactly what it looks like: a C# Read/Eval/Print Loop for Android devices. I intentionally kept things pretty simple for this version, so it’s a single line text input. This may change in the future, but having full editing brings in expectations of proper code completion, formatting, syntax highlighting, etc…all things I wanted to avoid for this launch. That said, there is in fact basic code completion. Whenever you type the “.” key, the compiler will try to find completion options for you. Typing code on a phone can be kind of annoying, so this was a necessary feature. Some other other features include:
- Namespaces can be quickly brought in using the built-in list of all available namespaces
- Declared variables are available throughout the lifetime of the current session
- Errors/warnings encountered are displayed after the code is executed
- Console.Out is captured and displayed as well
- Tapping on any executed code copies it back to the input box
- Pressing and holding on an error or warning allows you to copy the text or search the web for help
Come On Man, Let’s Get Technical
If you’re reading this blog, you might be more interested in how it was made than what it actually does. I do hope to open source it all sometime soon, but I want to clean some things up a bit before I do that.
First things first: as you might expect, the app is written entirely with Mono For Android. The compiler used in the app is based on the Silverlight port of Mono’s C# compiler service done by Frank Krueger. I’m using my own fork of it at the moment, in which I added a Mono For Android build, as well as a little hack to get things working properly for me. I ran into an issue where certain code completion requests would go off indefinitely, which would tie up a lock and prevent anything else from being executed. I added a quick hack that allowed me to terminate that call if I needed to. It’s not pretty but it works for now – that’s what forks are for right? Seriously though, I want to give major props to Frank on this. His work in the original port saved me a ton of time here.
In my project structure I was able to separate out a lot of the core compiler logic into a separate class library that doesn’t reference any Android code, which should hopefully allow me to create a Windows Phone 7 port at some point, time allowing. To help decouple things further, I’m using Steven Robbins’ TinyMessenger event aggregator/messenger library. This allows me to keep more of the app logic in the class library without it having to know any specifics of the environment. I’m not using TinyIoC in this project (yet), but it’s also a great little library that works well with Mono For Android.
I think that just about sums up the core parts of the system. The rest of the work mainly involved the Android side of things, where I learned some hard lessons on how much of a pain UI work is on Android. The code input box is a custom view I made that extends the standard AutoCompleteTextView to do what it needed to.
The app is also pretty large, by necessity. The APK is about 17MB, which installs to about 21MB (on my phone, at least).
So I know all that sounds pretty damn awesome, but I should probably mention some of the current limitations and problems. There were a couple problems I ran into with the Mono C# compiler service. The main one was an issue where if you tried to bring in a namespace and try to run some code again after getting an error the first time that the type could not be found, it still can’t find the type. I filed a bug report with them about this. A little annoying, but definitely not a showstopper.
I also had to prevent you from declaring classes within the app. The Mono compiler does actually support this, but for some reason when using it inside of Mono For Android, newing up an instance of that class will cause a crash deep in Mono. I’m hoping to be able to get this feature into the app in a future version.
Aside from those, the main issue is one of stability. From time to time, trying ot run some code will cause the app to just terminate unexpectedly. It’s not the input itself that is the problem. I think it may be related to garbage collection but haven’t been able to nail it down yet. This one sucks, so I’m definitely trying to get to the bottom of it as soon as I can.
Have Android, Will Compile
So there you have it. I’m definitely curious to see what everyone thinks, and also hear about how it behaves on various devices. In my brief beta period I had it tested on a few devices but I know that mileage can vary in the Android ecosystem, so definitely let me know if you see some issues. If you’re going to be at Monospace next week I’d be happy to show you the current source for the app if you’re interested. I may show some of it in my Android session on Saturday, time permitting. Happy compiling!