Mono for Android
Cross-Platform Development With Mono for Android
Writing code for the same mobile app across various platforms gets old in a hurry. Fortunately, there are solutions.
Many years ago, in fact pre-Java, I remember a hallway discussion about the desire to write a single application that could easily run across various platforms. At the time, we were only worried about writing applications on Windows 3.1 and Mac OS 7.x. There were many discussions about windows, user interface concepts, and specifically a rather long discussion as to whether Mac users would accept a Mac application that didn't have balloon help. Thankfully, the marketplace answered this question for us with the Windows API winning the battle.
A similar set of questions is currently going on in the mobile world. Unfortunately, at this point in time, there is currently no winning API and none currently in sight. What's a developer to do? Here are some questions that developers have (and there are many more):
- How can mobile developers target Android and the iPhone with the same code?
- How can .NET developers share their code across Android, iPhone and other platforms?
- How can developers give applications the look and feel of the specific platform and still allow as much code as possible to be shared?
- Mobile devices share many common features, such as cameras, accelerometers, and address books. How can we take advantage of them in a platform independent way and still give the users the look of every other application running on their platform?
In this article, we'll look at some solutions to these cross-platform and code-sharing questions between Mono for Android, MonoTouch and the .NET Framework available to developers.
I'm sure that you are thinking, "Hey Wally, this is .NET! I can just take a library, reference it in my project, and use it. Why are you dedicating an article to this?" Unfortunately, there are several reasons you can't do this; and you shouldn't do it, even if you could.
First off, .NET isn't quite .NET. When a library is compiled for one version of .NET, it doesn't work in another version of the framework. This means that a library compiled with the .NET 4 Framework doesn't work if you try to reference and use it in a Mono for Android or MonoTouch project. This is due to differences between platforms and compilers.
[Click on image for larger view.]
|Figure 1. Adding a linked file in Mono for Android.|
And it doesn't just happen between a .NET 4 library and Mono for Android/MonoTouch. The same issue occurs between .NET and Silverlight libraries and applications. There are also other issues at work that should keep you from just referencing a library. These include:
- There will almost always be some type of locking issue.
- If you don't reference the project, you must compile the library before you use any of its updates.
- How do you debug into the library without access to the source code?
As you can see, there are a number of issues, so let's examine the options.
Sharing Code and Projects
Don't worry; I'm not dumb enough to think that you would want to copy and paste code across various applications. How can you share code, keep it in one spot, and run it across various platforms? The sequence for sharing a single project across various platforms:
- Create a series of projects. In this sample, we'll create a Mono for Android project, a Mono for Android Class Library and a .NET class library. These projects will be placed within the same solution.
- Within the .NET class library project, create a class file.
- Within the Mono for Android project, we'll add a linked file. Usually, we think of adding files directly to our project as we use them; but we want to split our application's logic out, so that we can share the logic in Android applications, Honeycomb applications, Ice Cream Sandwich applications, MonoTouch applications, and other .NET applications. Adding a linked file can be seen in Figure 1.
- Once a linked file is created, you can see the linked file in the IDE. Note the change in the icon displaying the class file, shown in Figure 2.
Now we have some code that we can use within a Mono for Android application. The Net4Class.cs file can be shared code across other implementations of the .NET framework, such as Windows Phone or the iPhone with MonoTouch.
The thing to remember is that our class can only contain code that will only run across any platforms we want to target. For us, this will basically means that we need to support the .NET API available in the mobile world of Mono for Android, MonoTouch and Windows Phone.
Common Device Services
[Click on image for larger view.]
|Figure 2. The new icon for the linked file.
Devices in the marketplace share many of the same features. These features include a camera for taking pictures and recording video, geolocation for determining where the user is in the world, accelerometers for detecting shaking of the device and so on. There ought to be some way to interact with these features using a common API. Developers can handle this problem a number of different ways. They can:
- Continue to program against each platform's specific feature API. This will give the user a very platform-specific feel; however, it also means writing the most code.
- Write their own abstraction layer for these features. This will work, but it means a developer must then manage and support the abstraction layer. While it's an interesting exercise in computer science, this will result in the longest time to market due to the API that must be created, programmed to, and maintained.
Xamarin, which owns and maintains Mono for Android and MonoTouch, is aware of this common device services problem. They are currently working on a library called Xamarin.Mobile, the goal of which is to provide a common API to share some of these APIs. Let's look at the example code for performing a geolocation lookup in Mono for Android, shown in Listing 1, and MonoTouch, shown in Listing 2.
Looking at the two sections of code, you can see that the APIs to get location are the same, in spite of the differences between the Android and iOS platforms. For example, the PositionChanged and PositionError events are the same. Check out the PositionEventArgs class in the code. The properties are the same in both platforms, so developers are able to take their knowledge of location (or anything else in the Xamarin.Mobile Library) and transfer that across from Android to the iPhone and Windows Phone.
If you're thinking, "This is great, but we're .NET developers, so how do we also target Windows Phone?", have no fear: Xamarin is providing a Windows Phone implementation as well. This will allow you to use one API and perform operations across three mobile devices. This makes life easy for developers.
Please note that Xamarin.Mobile is currently a preview release.
But I Just Want to Recompile
Games People Play
Can't we just have a single application, and have it magically run across various platforms? Unfortunately, a UI that's the same across various platforms will not look like the other applications on these platforms. For the public consumer, this might be a deal killer; but there are numerous applications where this is acceptable. Think about a line of business applications where agents are continually inputting data. Designing a single application that looks the same across the various platforms may be acceptable. There are myriad options along these lines. An option that comes to mind is something like MonoCross and the Cell SDK. With these tools, you can build one application and recompile for the various platforms you want to hit.
Angry Birds has taken the world by storm. Who doesn't want to create the next great game? And when you create these games, you want to share the game code as much as possible.
The good news is that there are a number of cross-platform game frameworks that developers can use, like Unity and MonoGame. These are game frameworks that developers can use to create game applications that run across platforms.
The Portable Class Library Project
The Portable Class Library Project
is a set of Microsoft libraries and tools that allows development for one library that works across multiple project types without changes. Previously, we were stuck with targeting one platform, reworking, targeting a second platform, and on and on until we had support for all the necessary platforms.
This was similar in concept to the linking of files discussed earlier. Mono for Android doesn't currently support the Portable Class Library, but support is rather easy to add. Jonathan Pobst of Xamarin recently wrote a blog post on how to add this support. Check the references at the end of this article to get links to Jonathan's blog post and more information from Microsoft on their Portable Class Library Project.
There are many options for sharing code in Mono for Android with other .NET platforms. Many developers are currently asking this question. This article really just scratches the surface of what is possible. Let me point you to two book resources in the area of cross platform mobile development with C# that go into much greater detail as well as discuss other options:
- Greg Shackles' book, "Mobile Development with C#: Building Native iOS, Android and Windows Phone Applications". Shackles is a co-author of this column.
- The Wrox book, "Professional Cross-Platform Mobile Development in C#"
Wallace (Wally) B. McClure has authored books on iPhone programming with Mono/Monotouch, Android programming with Mono for Android, application architecture, ADO.NET, SQL Server and AJAX. He's a Microsoft MVP, an ASPInsider and a partner at Scalable Development Inc. He maintains a blog, and can be followed on Twitter.