Mono for Android

Better Debugging With Mono

The latest Android SDK provides an emulator with improved debugging capabilities. Mono for Android developers will appreciate the upgrades.

Let's be honest: When debugging with Android -- and Mono for Android (MfA) on Windows by extension -- using the emulator requires patience. This isn't a condemnation of Mono for Android; merely recognition of the reality of having to live within the Android ecosystem. I've noticed that most developers who develop on Android tend to be using a Mac. I think this is due to the development experience on the Mac being better overall for Android.

Let's look at how this debugging has improved recently for Windows developers targeting Android with C#.

Pain Points
Debugging performance has improved since the initial release of MfA, but it's still a bit painful to use in Windows. Let's look at some reasons.

  • The Android SDK provides an emulator to test applications, instead of a simulator. What's the difference?

The difference between an emulator and a simulator is subtle but significant. The best explanation I've read comes from Stack Overflow. Consider an old HP Calculator. You want to provide the calculator to your users. There are two ways to do this:

Method No. 1: When a user selects the keys on the display, the program performs the operations using software code. When a user enters a number, selects the "+" key and presses the equals ("=") key, the application adds the two numbers based on how the operating system actually performs the addition.

Because the calculator is using the OS's addition methods, the performance of the addition will be comparable to other operations on the computer. In this scenario, your program is "simulating" the calculator, so the calculator is referred to as a simulator. The iPhone SDK contains a simulator for testing. Debugging against the iPhone simulator is fairly quick and easy to work with. The downside is that a simulator does just that: It simulates, and may not take into account any edge cases that the calculator might.

The other strategy is to take a copy of the calculator's firmware and load that into your program. When a user performs operations, your code will load the calculator's firmware, pass the parameters into the firmware, get the result, and pass the results back to your program to be displayed to the user. This is referred to as emulation.

The positive is that performance is nearly always the same under emulation as it is on a device. The negative to this is that an emulator is typically slower due to the need to load the firmware and run what may be a very different computer architecture.

  • Nearly all mobile devices are based on ARM chips. These low-power chips aren't the  Intel-based x86 and x64 chips that dominate developers' systems. There isn't a one-to-one mapping of CPU-level instructions between ARM and the x86 processors.

Emulating ARM processors on an x86-based system requires a fair number of CPU cycles compared to the same operations on an ARM processor. The result is time spent translating ARM instructions to x86, causing small delays in the debugging process. As we all know, developers hate delays when debugging.

Unfortunately, the Android SDK has only provided an ARM-based emulator until very recently. The result is that debugging with the emulator feels slow, and that's being kind. Placing a breakpoint in the debugger and hitting the f10 key to step through code results in a delay of several seconds. Attempting to interrogate a local variable results in a similar slowdown. While it might not seem like much, it adds up. I know I easily get frustrated when digging into something complicated on the emulator.

Note that this isn't a problem just for Mono for Android; I was at an Android conference and was surprised at how many presenters and people were having problems with the Android development tools. This is why most developers prefer to debug on a hardware device.

Setup and Improvements in the Android SDK
The Android SDK Release 17 (r17) was made available in March, and there was talk it had an Android x86 emulator. I downloaded and installed r17 to try it out. (Note that since this was written, Google has provided two minor updates, r18 and r19, that are essentially bug fixes. They don't impact the content of this article.)


[Click on image for larger view.]
Figure 1. The Atom x86 system image needs to be installed.

The first task was to figure out what I needed to install. There were two items:

  • Intel Atom x86 System Image. This emulator image, shown in Figure 1, is available under the Android 2.3.3 API Level 10 option.
  • Intel Hardware Accelerated Execution Manager. This is underneath the Extras, and shown in Figure 2.

[Click on image for larger view.]
Figure 2. The other necessary part, the Intel Hardware Accelerated Execution Manager, is under Extras.

This got me the emulator as well as the Intel Hardware Acceleration Execution Manager.

Once I downloaded those, I needed to walk though setting up an emulator session and the accelerated execution manager.

Once I downloaded r17 with all the supporting code, I could run an x86 emulator. The emulator looks, smells and tastes the same as any other Android 2.3 emulator session. Notice in Figure 3 that the x86 emulator looks exactly like any other Android 2.3 emulator session.


[Click on image for larger view.]
Figure 3. The x86 emulator, provided in the Android SDK.
What about Mono?
Mono for Android has support for x86 Android systems. This can be seen and set via the project properties of an Android application, as shown Figure 4. Notice the x86 option at the bottom on the Application tab in project properties.


[Click on image for larger view.]
Figure 4. Checking the "x86" box at bottom makes code compatible with Intel-based devices.

Selecting the x86 checkbox ensures that your project will have x86-compatible code. Once your application is compiled into x86 code, the application can be deployed to an x86 emulator session, just like an ARM emulator session. Figure 5 shows an Intel x86 emulator running on port 5554, and an ARM emulator running on port 5556. The two are indistinguishable from the Mono for Android toolset.


[Click on image for larger view.]
Figure 5. The device selector, showing emulation for x86 and ARM devices.
Debugging in the x86 Emulator
Now that everything was set up for the x86 emulator, I looked at the development experience, starting with the example Mono for Android application.

I was impressed with the speed. I didn't detect any performance issues when stepping through code. Interrogating objects happened immediately. Running a project in the debugger resulted in response similar to debugging any other type of application.

It was a great experience, so I decided to open up more of my projects. Each one of the projects ran properly in the x86 emulator. Some of these were simple example applications that explored one or two operations, while others were multithreaded. Each showed strongly improved performance running in the debugger, stepping through code and interrogating objects. As shown in Figure 6, the breakpoint is hit and the watch window displays the variable's value. Both of these operations were blazingly fast.


[Click on image for larger view.]
Figure 6. Debugging is fast in the emulator.

Use Cases
So, should you trust the x86 emulator with everything? I don't think any developer should depend on an emulator for all testing; I think it's a good place to start and perform initial development, but I wouldn't use it as a replacement for testing on a device.
Also note that the support for the x86 emulator is early on. Every application I've tried has worked, including several multithreaded examples. But there are a few things I've found that aren't currently working smoothly. However, introducing the x86 emulator is a good first step in improving the entire debugging experience for Android. It's a testament to the folks at Xamarin that they already have support at this early stage.

Xamarin Support
I've been amazed at how well Mono for Android provides support for the x86 emulator, even early on. This is due to the choice to interface with the Android SDK via defined tools and APIs. Because Mono for Android hasn't spent a lot of time trying to recreate the wheel and the Android APIs, developers get the benefit of the new features in the Android SDK with very little delay.

I've talked with the folks from Xamarin, and know that the x86 emulator is on their radar. I feel really confident that Xamarin will be doing several things to improve the debugging experience and provide "more better" integration with the x86 emulator over the coming months. This is a great time to be a C# and .NET Framework developer exploring Android.

About the Author

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.

comments powered by Disqus

Featured

  • Compare New GitHub Copilot Free Plan for Visual Studio/VS Code to Paid Plans

    The free plan restricts the number of completions, chat requests and access to AI models, being suitable for occasional users and small projects.

  • Diving Deep into .NET MAUI

    Ever since someone figured out that fiddling bits results in source code, developers have sought one codebase for all types of apps on all platforms, with Microsoft's latest attempt to further that effort being .NET MAUI.

  • Copilot AI Boosts Abound in New VS Code v1.96

    Microsoft improved on its new "Copilot Edit" functionality in the latest release of Visual Studio Code, v1.96, its open-source based code editor that has become the most popular in the world according to many surveys.

  • AdaBoost Regression Using C#

    Dr. James McCaffrey from Microsoft Research presents a complete end-to-end demonstration of the AdaBoost.R2 algorithm for regression problems (where the goal is to predict a single numeric value). The implementation follows the original source research paper closely, so you can use it as a guide for customization for specific scenarios.

  • Versioning and Documenting ASP.NET Core Services

    Building an API with ASP.NET Core is only half the job. If your API is going to live more than one release cycle, you're going to need to version it. If you have other people building clients for it, you're going to need to document it.

Subscribe on YouTube