It’s been a very relaxing two weeks in which I have been offline. And I mean really offline. My phone didn’t work, no internet connection at hand. That doesn’t mean however I haven’t been coming up with cool ideas and reading up on stuff. A nine hour airplane ride isn’t the most exciting thing to do, so I had plenty of time to think If you must know: I have been 14 days away to Curacao. You should be going there too if you have the time! It’s very relaxing and very sunny.
So what have I been up to? Reading more Android stuff and trying to think up a way to tell people how cool MonoDroid is for Android development. In this article I will show you just that by showing some of the basics.
A general introduction
This article is all about MonoDroid, but before I talk about that I should explain what environment this is all about. The stuff I’m about to show you is all Android based software. This means it will run on Android tablets and mobile devices. Android is an operating system produced by Google. Android contains libraries for developers to write applications for mobile devices and a set of standard applications that users can use. Android runs on practically any device that has any form of real processing power. Sorry for those of you that still have a nokia classic device or some other black-and-white phone. It will not run on that.
Android is in many ways different from the other major mobile platforms that are popular today. Both Apple’s iOS and Microsoft’s Windows Phone 7 target high-end devices at the moment. Android runs on high-end devices as well as  budget smartphones. This means that the target audience is a lot bigger. Microsoft has said that there will be budget devices available soon so for those of you that are building apps for Windows Phone 7, there’s good news for you guys too.
Besides the broad public there’s also a difference in what you can build in terms of applications. Android allows you to build applications and services instead of just applications. The difference here is that applications (apps) work very similar to the way they work on Windows Phone 7 and iOS. You cannot run multiple applications at the same time. The operating system limits this to save much needed memory and CPU power. Services on the other hand are kept in memory much longer as they need a way to provide notifications or start apps when events on the device occur. On Android you can build these services yourself. On other devices this isn’t allowed, except when you’re a device manufacturer.
The rest of Android is pretty much what you might expect from any mobile operating system. You can build apps that access information from the internet, use the build-in GPS, compass, accelerometer and other sensors on the device and of course use the phone functionality (I know, who needs that these days).
A less general introduction or what is MonoDroid
Now that you know Android, it’s time to complicate things. All applications on Android are built using C++ or Java, but mostly and by that I mean at least 90% Java. But that’s not all. The guys at Novell produced a framework called MonoDroid to build CLR-based applications on Android. I’m refusing the term .NET here since that doesn’t do it justice at all. MonoDroid is a combination of a compiler that produces CLR assemblies for Android. To make this possible they produced a set of Android Callable wrappers to communicate from the Android/Java world to the CLR/MonoDroid world and a set of MonoDroid callable wrappers so that your apps can use the Android infrastructure. In practice this means you get a very .NET-like experience on a platform that is otherwise completely java-fied (If I use this term enough,I’m pretty sure that it will end up in someone else his vocabulary too).
The MonoDroid libraries contain “wrappers” for the complete Android system. Wrappers is explicitly placed between quotes, because although they are all wrappers, you can’t really tell, because Novell took special care in producing something that adheres very closely to the .NET way of living. On top of the Android wrappers they have sprinkled a very thick layer more of .NET goodness. You’ve got Linq, WCF, the full set of collection classes and a lot of the other .NET utilities that the typical developer is used to.
Getting started
To start building a MonoDroid application you need Visual Studio 2010 standard or better (Of course I recommend using ultimate, but that’s for a very different reason). Also you will need to download a couple of extras:
- MonoDroid – http://go-mono.com/monodroid-download/
- Android SDK – http://developer.android.com/sdk/index.html
Be sure to use the .exe version of the Android SDK. This ensures that you have the correct registry settings needed by MonoDroid to locate the android emulator and related components.
After you have installed all the goodies onto your computer you should have a new set of project templates inside Visual Studio 2010.
You can either create a MonoDroid library or a MonoDroid application. Most of the time you will be producing only applications so pick the Application project type when creating a new app. While you’re at it, you should probably give it a cool name too.
After creating the new project you will end up with a project structure that looks very similar to what you get when you create a new app in the Eclipse IDE with just the Android SDK.
Note: Here’s a good tip. Don’t just search for MonoDroid on Google. Search for Android too, it will turn up more sources for information and with a little tweaking it will all work very well in MonoDroid too. The only difference is that event listeners are translated into events in MonoDroid and setter and getter methods are translated into properties.
The new project contains an Activity class and a couple of resources in the Resources folder. The Resources folder has a specific structure. The structure corresponds to the requirements described in the various sections of the Android SDK manual. The main thing you need to keep in mind is that the layout folder contains layouts for the GUI, the values folder the strings for localisation and the drawable folder contains drawables for the various icons in the application.
Implementing activities
In the previous section I’ve mentioned the Activity class. Android apps aren’t build like normal apps. Each app contains a number of activities that you offer as part of a device. This means that other apps can use activities from your app as long as they know the name of the activity. You can even publish your activities with a known name, so that others can find the activity more easily.
Note: Why reuse activities? Well, because google thought it would be a good idea for developers to be able to replace the standard functionality offered by the Android operating system. You can replace the addressbook with your own addressbook activity if you want. This offers manufacturers of devices to implement their own activities to offer a unique style or method of interaction. Improves the sales.
An activity written in MonoDroid looks like this:
[Activity(Label = "MonoDroidApplication1", MainLauncher = true,Name="MyFancyActivity")] public class Activity1 : Activity { /// <summary> /// Called each time the activity is (re)started. /// </summary> /// <param name="applicationState">Contains the state of the application</param> protected override void OnCreate(Bundle applicationState) { // Make sure you invoke the base operation first. // Things will go bad for you if you don't base.OnCreate(applicationState); // Set our view from the "main" layout resource SetContentView(Resource.Layout.Main); // The layout contains a button. You can find it using FindViewById. // Resource.Id contains every id you used in the resource files. Button button = FindViewById<Button>(Resource.Id.MyButton); // Bind events to controls like you would normally do button.Click += new EventHandler(button_Click); } /// <summary> /// Invoked when the OS decides to nominate the activity for cleanup. /// </summary> /// <param name="applicationState">Container for the application state</param> protected override void OnSaveInstanceState(Bundle applicationState) { base.OnSaveInstanceState(applicationState); //TODO: Save any information you want to be kept alive in the application state } void button_Click(object sender, EventArgs e) { } }
Each activity is based on the Activity class and is marked with the Activity attribute. The activity attribute tells the MonoDroid build process to generate an activity element in the manifest of the application with the settings provided in the attribute properties. Each Android application requires a manifest to operate correctly. This manifest tells which permissions the app needs and what activities and services it offers.
The MainLauncher setting in the Acitivty attribute tells android to show the activity in the launcher on the device. Other activities that you don’t want to be launched directly by the user should not have this setting or if you want to have it, it should be set to False.
An activity has UI elements associated with it. You can build them from code, but usually it’s better to use layout files for that. To load a set of UI elements, you invoke SetContentView with the ID of the layout you want to load. The Android runtime will read the layout file and display it on screen.
Layout files are specified using a XML dialect called Android XML. There’s not much I should tell you about this, except that you always need to have the following XML declaration href=”http://schemas.android.com/apk/res/android”>http://schemas.android.com/apk/res/android”. To give you a sense of what a layout looks like, here’s an example:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout target="_blank">MonoDroid website. They have all kinds of tutorials that help new MonoDroid developers on their way quickly.After you have created the layout and loaded inside your activity, you can access controls in the layout by using the FindViewById<T> method. This method accepts the ID of the control and looks it up in the layout. If it can’t find the control, it will simply return a null reference.  After you have a reference to the control you want you can attach events to it or manipulate the properties of the control directly like you would in Windows Forms.
Normally you get an activity that looks like the sample above, except for the OnSaveInstanceState method. I’ve added it to the activity to make you aware of the state saving logic in Android. Activities don’t live forever after you have launched them. Although it may look that way, because there’s no close button, the operating system decides whether an activity should stay active or it should be removed from memory. There are a lot of states for any activity, but here’s the important thing to know about activity states.
Everytime the OnCreate method is invoked you should check if there’s any previous state available. If this is the case you should use that state to restore any values in controls you have previsously saved the state for. You can save the state of your app in the OnSaveInstanceState method by putting values into the application state bundle. The operating system will save this bundle with your app and load the bundle back into memory when the application is started again.
Launching other activities
There are apps that work with just one activity, but most apps don’t. They have a set of activities that represent different use-cases if you will. The user usually launches one of the activities and navigates to other activities from there by selecting things on the screen or by pusing buttons. The applicatin listens for events and can launch different activites to allow the user to perform the task they want to.
To launch an activity you need to tell Android which activity you want to launch. This can be done by specifying a well known name of an activity or by specifying the type of the activity to launch. The first option is usually used for things like launching the camera, the addressbook or the webbrowser. The second option is used to launch activties that are part of your app.
Every activity is launched by invoking the StartActivity that accepts the Intent of what you want to do. An intent tells the operating system what you want and contains several settings to tell the operating about how to handle the intent. For example, should it use a separate process to launch the activity.
void button_Click(object sender, EventArgs e) { Intent intent = new Intent(this, typeof(MySecondActivity)); StartActivity(intent); }Just starting activities isn’t the only thing you can do. You can also start an activity as if it is a dialog and get a result back when the activity is completed. To do this you need to start the activity using StartActivityForResult and specify a resultcode to identify the action by. When the activity is finished you will get the results back in the OnActivityFinished method that you can override in the parent activity.
void button_Click(object sender, EventArgs e) { Intent intent = new Intent(this, typeof(MySecondActivity)); StartActivityForResult(intent, 42); }Inside the OnActivityFinished method you can check the result of the user action and get any data returned by the activity by invoking Get…Extra methods on the Intent instance that is returned by the activity after it’s finished.
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) { base.OnActivityResult(requestCode, resultCode, data); if (requestCode == 42) { if (resultCode == Result.Ok) { int selectedItem = data.GetIntExtra("Question",0); } } }In the previous section I explained that finishing activities isn’t voluntary. Well, not exactly. Authors of activity can explicitly finish an Activity by invoking the Finish activity inside the activity. This method can be used as is. If you however need to return a result to the parent activity you need to use the SetResult method and call the Finish method directly after that.
void button_Click(object sender, EventArgs e) { Intent intent = new Android.Content.Intent(); intent.SetClassName(this.ApplicationContext, "MySecondActivity"); // Place the selected item in the intent intent.PutExtra("Question", 10); // Set the result of the activity SetResult(Result.Ok, intent); Finish(); }The SetResult method accepts the Result (OK or Cancel) and an intent containing the extra data to be returned to the parent activity. The parent activity gets the intent and resultcode back in the OnActivityResult method so it can handle the outcome of the child activity.
Other things you can do as part of your activity
It’s pretty clear that what I described to you in the previous section isn’t all there is. You can do a lot more, but as with all blogposts, articles and presentations: I don’t have endless space to show it all. But you can be sure I will show more in the near future as MonoDroid is a really powerful and easy platform to work with. For now, here’s a list of things that are interesting to check out:
Note: This is probably a good time to tell you that it is possible to use WCF. The only problem is that you don’t have the Add Service Reference dialog to you when you create a MonoDroid app in Visual Studio 2010. Instead use svcutil.exe from the Windows SDK v7.0 (Don’t worry, you got it when you’ve installed Visual Studio 2010).
Running and debugging the app
Android applications can be debugged either on the device itself or inside the emulator. For MonoDroid applications this means that you can attach Visual Studio to a device to debug the app or just press F5 to start the emulator, deploy the app and debug it.
Note: At the moment of writing the debugger works and most of the time it shows you the exceptions you want to see when it goes wrong. However it’s good to know that the product is still in beta testing and sometimes things break deep inside the engine. This means you won’t get an exception and sometimes Visual Studio 2010 will just hang forever waiting for the the emulator to return the call. You will definitly get more information with the Adb tooling provided by google in these situations.
You can set breakpoints in your code and specify watches to check what’s going on in the app, just like you would do with any normal .NET application. There’s even a device logger window available inside Visual Studio, which shows you more about what’s going on.
Tips for learning MonoDroid
Back when I started learning MonoDroid there was no documentation for it. It has improved since, but there are still more articles about Android development than there are about MonoDroid development. Here are a few tricks I used to get the most out of learning MonoDroid:
- Definetly install Eclipse before installing the Android SDK. It helps greatly if you can move over to Java and try things out there. It gives you a better sense what is actually broken. If it does work there, you are probably encountering a bug in MonoDroid. If it does work there, you are going wrong somewhere with your code and the Java code should give you a pretty good idea about where exactly.
- Don’t be afraid to start up the “adb logcat” command from the android SDK folder. It does give a lot more information directly from the operating system log facility. You’d be surprised just how helpful it can be even with a MonoDroid API doing all kinds of weird stuff to get Java connected to .NET.
- Read blogposts and tutorials for Android. They should a very very big part of what’s possible with the operating system. You can access all that from MonoDroid. Be prepared to learn more Java than you ever wanted to, because it’s all written in Java and you need to know a good deal about that to make sense of the how and why behind some of the concepts.
- Buy a book about Android. Just like with the blogposts and tutorials you need to know your Java. Some books however have a small Java tutorial included to get you going and it’s usually enough to understand the rest of the book.
- Be sure to check out the website http://mono-android.com/ the Novell guys are updating it right now to include more tutorials, guides and documentation about MonoDroid. It improves almost every week.
- Join the mailinglist. The developers are on there too and they read the mails coming in. If you have a good question they will answer it. Very helpful, especially if you find a potential bug.
Final words
Download it people! You will love it. MonoDroid is easy enough to learn especially if you’ve done .NET before. If Java puts you off, don’t worry, sooner or later the Java bits will all be a thing of the past. Remember, I used it to learn it in a period where there was no documentation and I’m weird enough to understand and like both it doesn’t mean you should too.
For those of you who would like to contact me about this, there’s an e-mail form on my blog and you can also find my on twitter @wmeints.