(Android) Emulator on Hyper-V

An apparently great news is that Microsoft has been cooking up an Android emulator. It appears that every company now feels compelled to create one. Right now we have Google’s emulator, Intel HAXM support for it, Genymotion, Xamarin Android emulator and now the Visual Studio’s one. It is getting crowded, isn’t it?

So, why I did write an apparently great news. Because the VS Android emulator, just like Windows Phone emulator, runs on top of Hyper-V. Which is not bad from the technical point of view but it is certainly not a good option on a developer machine. And that’s because turning on Hyper-V means that no other virtualization host can coexist. That’s right, forget about VMWare Workstation and Virtual Box when Hyper-V is turned on. Which makes sense on a server but on a developer machine it is sort of silly. The solution? According to Hyper-V crowd it is simple:

Just reboot with Hyper-V turned on or off, depending on your needs.

Which is … silly and really annoying. Heck, even Microsoft acknowledges this problem and it even lists it as one of the motivations beneath Visual Studio’s Emulator for Android:

Conflict with Hyper-V on Windows. Many emulators require you to disable Hyper-V or don’t work as well with Hyper-V as they do without. Using Hyper-V is part of the development setup for many developer activities, so asking you to restart your machine (multiple times a day) to toggle Hyper-V is not acceptable.

I agree that switching Hyper-V on and off is not acceptable. Bot nor is this solution. Instead of getting rid of (or modifying) Hyper-V when it comes to emulators, Microsoft decided to start creating all sort of emulators based on Hyper-V instead. Which is somehow conflicting with the awesome direction of open sourceness and multi platforms MS recently took. On the one hand they are going all nuts with open source and collaboration with other OS (amazing, btw) while on the other hand they are trying to monopolize virtualization on workstation machines. In the times when a mobile developer has to work with all sorts of different tools and software!

Other issues with the Hyper-V based emulator are that they require SLAT support (won’t run on older CPUs) and that they require Windows 8.x Pro or better. Both VMWare Workstation and Virtual Box run on “every” Windows you throw at them. Ah, and don’t forget that it will hardly support Google Play out of the box due to the Google’s silly restrictions (no emulator is allowed to ship Google Play except Google’s own).

So, the bottom line is, that yet another Android emulator is welcome, but it could be done much better. I’ll probably stick with Genymotion for the time being, since it works regardless of Hyper-V and is more feature packed that the rest.

Different XAML layouts for different device orientations in Xamarin.Forms

In case you’ve been wondering how to achieve different XAML layouts for different device orientation with Xamarin.Forms (just Forms from now), here is a solution. The thing is that there is currently no support for this. There is support for different layout when it comes Phone vs Tablet (OnIdiom<T>) or when it comes to different OS (OnPlatform<T>) but the thing is that these guys are static. They do their work once and that’s it. They won’t react to changes and it makes sense, since underlying OS or device type don’t change during runtime.

So something different is need. But before I even start with the XAML there is an important part that has to be done – getting the current orientation, or better, rotation at the Portable Class Library level. It is a twofold solution.

Here is code that exists in PCL project and isn’t OS specific.

public enum Rotation
{
    Rotation0,
    Rotation90,
    Rotation180,
    Rotation270
}
public static class Orientation
{
    private static Rotation rotation;
    public static EventHandler RotationChanged;
    public static Rotation Rotation
    {
        get
        {
            return rotation;
        }
        set
        {
            if (Rotation != value)
            {
                rotation = value;
                OnRotationChanged();
            }
        }
    }

    public static bool IsLandscape
    {
        get
        {
            return Rotation == Rotation.Rotation90 
                || Rotation == Rotation.Rotation270;
        }
    }

    private static void OnRotationChanged()
    {
        if (RotationChanged != null)
            RotationChanged(null, EventArgs.Empty);
    }
}

And here is the OS specific part where you set the orientation.

Android version:

public class MainActivity : AndroidActivity
{
    protected override void OnCreate (Bundle bundle)
    {
        UpdateCurrentRotation();
        base.OnCreate (bundle);

        Xamarin.Forms.Forms.Init (this, bundle);

        SetPage (App.GetMainPage ());
    }

    public override void OnConfigurationChanged(Android.Content.Res.Configuration newConfig)
    {
        base.OnConfigurationChanged(newConfig);
        UpdateCurrentRotation();
    }

    private void UpdateCurrentRotation()
    {
        switch (WindowManager.DefaultDisplay.Rotation)
        {
            case  SurfaceOrientation.Rotation0:
                Orientation.Rotation = Rotation.Rotation0;
                break;
            case SurfaceOrientation.Rotation90:
                Orientation.Rotation = Rotation.Rotation90;
                break;
            case SurfaceOrientation.Rotation180:
                Orientation.Rotation = Rotation.Rotation180;
                break;
            case SurfaceOrientation.Rotation270:
                Orientation.Rotation = Rotation.Rotation270;
                break;
        }
    }
}

Windows Phone version (note that you have to set SupportedOrientations="PortraitOrLandscape" in your MainPage.xaml to enable rotation of the page):

public partial class MainPage : PhoneApplicationPage
{
    public MainPage()
    {
        InitializeComponent();
        UpdateRotation();
        Forms.Init();
        Content = App16.App.GetMainPage().ConvertPageToUIElement(this);
    }

    private void UpdateRotation()
    {
        if ((Orientation & PageOrientation.PortraitUp) 
== PageOrientation.PortraitUp) App16.Orientation.Rotation = Rotation.Rotation0; else if ((Orientation & PageOrientation.PortraitDown)
== PageOrientation.PortraitDown) App16.Orientation.Rotation = Rotation.Rotation180; else if ((Orientation & PageOrientation.LandscapeLeft)
== PageOrientation.LandscapeLeft) App16.Orientation.Rotation = Rotation.Rotation90; else App16.Orientation.Rotation = Rotation.Rotation270; } protected override void OnOrientationChanged
(OrientationChangedEventArgs e) { UpdateRotation(); base.OnOrientationChanged(e); } }

Sadly I have no iOS device at this time, but it should be pretty easy to support it as well.

At the beginning of the page/activity and each time orientation changes the current rotation is sent to Orientation class in PCL.

At this point we have the rotation information and event RotationChanges that notifies about changes in rotation. Now this information can be used to achieve the dynamic layout changes.

For that purpose I’ll use a Grid ContentView derived class that can be nicely used with XAML.

public class Rotational: ContentView
{
    public View Landscape { get; set; }
    public View Portrait { get; set; }
    public string LandscapeType { get; set; }
    public string PortraitType { get; set; }
    private bool isPortrait;

    protected override void OnParentSet()
    {
        base.OnParentSet();
        VisualElement view = ParentView;
        while (!(view is Page))
        {
            view = view.ParentView;
        }
        Page page = (Page)view;
        page.Disappearing += page_Disappearing;
        page.Appearing += page_Appearing;
    }

    void page_Appearing(object sender, EventArgs e)
    {
        Orientation.RotationChanged += CurrentOrientation_Changed;
        Update();
    }

    private void CurrentOrientation_Changed(object sender, EventArgs e)
    {
        Update(); 
    }

    void page_Disappearing(object sender, EventArgs e)
    {
        Orientation.RotationChanged -= CurrentOrientation_Changed;   
    }

    private void Update()
    {
        if (Content == null || Orientation.IsLandscape && isPortrait ||
            !Orientation.IsLandscape && !isPortrait)
        {
            Children.Clear();
            if (RhOrientation.IsLandscape)
{
isPortrait = false;
if (Landscape != null)
{
Content = Landscape;
}
else
{
View child = FindContentView(LandscapeType);
Content = child;
}
}
else
{
isPortrait = true;
if (Portrait != null)
{
Content = Portrait;
}
else
{
View child = FindContentView(PortraitType);
Content = child;
}
} } } private View FindContentView(string contentViewName) { var query = from t in GetType().GetTypeInfo().Assembly.DefinedTypes where t.IsClass && !t.IsAbstract && t.IsSubclassOf(typeof(ContentView)) && t.Name == contentViewName select t; var contentViewTypeInfo = query.SingleOrDefault(); if (contentViewTypeInfo != null) { ContentView page = (ContentView)Activator.CreateInstance
(contentViewTypeInfo.AsType()); return view; } else return null; } }

The class is named Rotational and defines four properties: Portrait, PortraitPage, Landscape and LandscapePage. Portrait and Landscape are of type View and you can store View derived classes that would appear based on orientation. Here is an example:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                       xmlns:v="clr-namespace:App16;assembly=App16"
                       x:Class="App16.TestPage">
  <v:Rotational>
    <v:Rotational.Landscape>
      <StackLayout Orientation="Vertical">
        <Label Text="Landscape" HorizontalOptions="Center" />
      </StackLayout>
    </v:Rotational.Landscape>
    <v:Rotational.Portrait>
      <StackLayout Orientation="Vertical">
        <Label Text="Portrait" HorizontalOptions="Center" />
      </StackLayout>
    </v:Rotational.Portrait>
  </v:Rotational>
</ContentPage>

Note that namespace declaration is required (xmlns:v="clr-namespace:App16;assembly=App16"). The above definition will show a label saying Portrait or Landscape, depending on device rotation and will change dynamically. The drawbacks of this approach are that both configurations are in-memory and the page might become a bit bloated.

Hence the second pair of properties: PortraitPage and LandscapePage. These are of string type and allow to enter the page class names the content of which will be used dynamically. Here is an example:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:v="clr-namespace:App16;assembly=App16"
                       x:Class="App16.TestPage">
  <v:Rotational PortraitType="PortraitTestContent" 
LandscapeType="LandscapeTestContent" /> </ContentPage>

Additional two pages are required (PortraitTestContent.xaml and LandscapeTestContent.xaml):

<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
                       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                       x:Class="App16.PortraitTestPage">
    <Label Text="Portrait test" VerticalOptions="Center" 
HorizontalOptions="Center" /> </ContentView> ... <ContentView xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="App16.LandscapeTestPage"> <Label Text="Landscape Test" VerticalOptions="Center"
HorizontalOptions="Center" /> </ContentView>

The pages are found using reflection and based on their names (no namespace is used).

This method is more memory efficient since it loads required content on demand and discards it afterwards. On the other side it is slower due to the loading of the page.

So, here you have it. What do you think? Is there a better way?

The sample is attached.

Rotational.zip (77.2KB)

Update 1: Instead of dynamically loading ContentPage and then using its content, ContentView should be used (it is XAML supported). That'd be a change in FindPageElement method to FindContentView.
Update 2: Changed base type for Rotational from Grid to ContentView.

Note: sample hasn't been updated from original version.

An alpha version of memory profiler for Xamarin Android

Memory profiling is one of the pillars of a good application. Even more important is on mobile devices since memory is usually scarce there. But sadly, there is no memory profiler for Xamarin Android development. Actually there is some raw support but lacks UI and friendliness. Hence I’ve built my own memory profiler.

This is an alpha quality version.

How it works

Since version 4.14 Xamarin has a (not) very visible support for memory profiling. But even with this support it isn’t easy to profile. With each garbage collection a log file is written on the device containing all the relevant data in a text format. Note that once you turn profiling on with

adb shell setprop debug.mono.profile log:heapshot

This setting is global and it works on all Xamarin apps on the device. Remember to turn it off afterwards if you don’t need it anymore to avoid, I guess, a huge performance hit.

There are two problems with the existing support here:

  • hard to trigger a garbage collection manually
  • hard to analyze data

My solution tackles both problems. The solution is divided into two parts.

Server side

The library available through NuGet does two things:

  • broadcasts its presence through UDP
  • allows triggering garbage collection from client

The library supports API Level 4 (Xamarin v1.6) and above.

Here is the NuGet package URL. You can also install it using this Package Manager Console command:

Install-Package RhMemProfiler.Server –Pre

The package is marked as prerelease and it won’t appear in NuGet Package manager if it isn’t set for Include Prerelease.

Once package has been added go ahead and create a global variable of type RhMemProfiler.Server.Beacon and initialize it with a friendly name and package name, like:

RhMemProfiler.Server.Beacon beacon;
….
beacon.Start("your friendly name", PackageName);

PackageName is the name of your package and it is ContextWrapper’s property.

Client side

This is a Windows application distributed through ClickOnce. After installation you’ll be prompted to open the firewall for the application. This is required since it, well, uses UDP and TCP to communicate with the server side.

profilerPrivate networks access is enough unless your mobile device is running on public network.

Once that is done you’ll be presented with a main window:

profiler

If your application on mobile device/emulator is running then you’ll see at least one option (one per IP on the device) in the combo box left of Connect button. That list contains friendly name (used when initializing on server) and its IP address. Pick any of them (IP doesn’t matter at this time). Hit Connect button.

If connection is successful you’ll see Conncted text in bottom left corner. If this is the first time you are connecting and/or memory profiling isn’t enabled yet on the device then you’ll be presented the Enable Profiling button, like:

enableprof

Enable profiling, restart mobile device application, disconnect, connect again and your are good to start memory profiling:

enableprof

Once there were at least two garbage collections and a snapshot has been taken afterwards you are able to compare them by selecting start and end version.

Collect Garbage … forces garbage collection on the mobile device
Snapshot … collects memory profiling log file from the device
Disable profiling … disables profiling on the device (profiling is per device, not per application – it affects all Xamarin apps on that device)
Only with source … shows only types from your package
Group panel … lets you group columns
Start and End … memory profile versions to compare to

Test

Imagine I have a class

public class MemLeak
{
    public string Value;
}

and a list of these somewhere defined. If I do a garbage collection before, when list is empty, and after one instance of MemLeak has been added I’ll see something like this when comparing before and after:

leak

It is pretty much obvious that the count of MemLeak instances increased by 1 and there are total of two instances of it around (actually I created one before that’s why there are two of them).

Memory profiling strategy

Memory profiling works by comparing state before and after. Usually a garbage collection is taken before some action and after that action. If the number of some instance increased without a valid reason it means that the application is leaking memory. Professional memory profilers help you even pinpointing the source of the leaks, however in our case, Xamarin doesn’t have that data available through this strategy.

Known limitations

  • ADB has to be in the path.
  • Only one device or emulator can be connected to the computer at the same time (the combo lets you pick the application but not the IP)

Final words

This is an alpha release, so be gentle with it and do not complain if your computer explodes because of it. It is something I wanted to release even at this stage for you to play with. It is actually pretty functional. So, feedback is appreciated and so are questions but I don’t guarantee anything, the development is done in my spare time (like that there is any Smile) for now. Hope you’ll find it useful.

Troubleshooting memory leaks in Xamarin.Android

I was testing an application I am building with Xamarin/Android. One of the tests was rotating the device while Google Maps fragment being shown. By default each time the orientation changes the activity and its views/fragments are recreated. IOW it is a good test for possible memory leaks because the recreation can be frequent.

I was quite surprised seeing a huge memory increase each time. Those eventually lead to an OutOfMemory in Java stack somewhere in Google Maps. After double checking that managed Xamarin code wasn’t leaking (i.e. retaining the said fragment somehow) anything I was starting to wonder whether Google Maps fragment is leaking internally. Perhaps only when combined with Xamarin. That’d be odd but not impossible.

Thus I started Android Studio and crafted a repro in pure Java. It wasn’t leaking. Thus it must have something to do with Xamarin. But what? Xamarin is providing a component to Google Maps (.net wrapping). Is it possible that there is a problem? Switching back to Xamarin and a few more tests later I couldn’t create a non leaking version. No matter what I did I still got leaks.

Suspecting a problem within Xamarin somewhere I decided to report a bug to bugzilla (Xamarin’s bug reporting web, not support) about it and mail a question to Xamarin support. The Jonathan Pryor’s response on bugzilla was lightning fast. In an hour or so he solved the mystery. The response from official support line was fast as well. (kudos to Xamarin on both).

It turns out that I was bitten with unmanaged memory pressure issue. Actually with unmanaged managed memory pressure issue. The thing is that Xamain/.net doesn’t know anything about unmanaged memory consumption. This is well known to .net developers, or at least, it should be. So, if you allocate a huge unmanaged piece of memory the .net won’t know about its size and won’t fire garbage collection automatically when it is released even it you are running low on memory (there are ways to let it know the memory consumption but that isn’t automatic). That’s usually valid for native code. But in the case of Xamarin, Java part is also unmanaged code to Xamarin (albeit Java is managed, but managed within Java with its own garbage collector).

Each time the Google Maps fragment was created and destroyed Xamarin created and “released” a single reference to maps fragment. By released I mean it was referenced from anywhere anymore and thus available for garbage collection by Xamarin garbage collector. But since .net saw only few bytes in that reference (which in turn referenced a ton of Java objects) it didn’t fire garbage collection automatically (and Java garbage collector couldn’t reclaim the memory because it was referenced by Xamarin) thus memory usage was increasing by huge steps. Strictly speaking this wasn’t a memory leak because all the memory would be reclaimed eventually - when garbage collection would run.

And that’s exactly how I solved it – I now run a manual garbage collection at least upon fragment creation (to reclaim the memory used by previous one). Problem solved. The bottom line is that you might run manual garbage collection after releasing a reference to Java object which internally uses plenty of memory. Also, calling Dispose on Xamarin objects helps (they might release reference to Java’s counterpart). In my case I couldn’t call Dispose because my fragment was created by layout inflation (actually I guess, I could by obtaining a reference to it, but that wasn’t obvious nor it might not help).

Here is more about Xamarin Garbage Collection.

Json.NET, Android/Xamarin and date serialization

In case you are using JSon.NET with Android/Xamarin you might encounter an “Object null reference” exception when trying to serialize (and probably deserialize as well) a type that contains DateTime property. The null object in question is TimeZoneInfo.Local.

This error happens when Android has no time zone set and thus Xamarin doesn’t set that property because it doesn’t know what time zone to use. There is a simple test where you can inspect Android’s time zone settings, just fire this command line:

adb shell getprop persist.sys.timezone

If it returns a blank line it means you are in trouble. A simple workaround for development is to set manually Android’s time zone through Settings/Date & Time or just fire another command line (i.e. setting time zone to Belgrade):

adb shell setprop persist.sys.timezone Europe/Belgrade

This works when using Genymotion emulator. Other than this there is no way to manually set the TimeZoneInfo.Local (perhaps it might be set through reflection, didn’t try it) which means your application won’t work in affected devices. Luckily the bug has been fixed and Xamarin will default to time zone defined by Java.Util.TimeZone.Default.ID. So, hopefully, the problem will go away for good.

A memory profiler for Xamarin.Android

Here is a first ever snapshot of my home-grown memory profiler for Xamarin.Android.

While very spartan it does the core job – comparing two snapshots for objects with growing instances (aka memory leaks). An array of Autofac.Core.IRegistrationSource[] is showing its references (one root, one to a List<>).

There you. Interested?

PS. Sample features DevExpress WPF components, chiefly XpfGrid.

Invoking DatePickerDialog asynchronously with Xamarin.Android

Invoking a DatePickerDialog in Xamarin.Android is a bit tricky because it is done through callbacks and at the end one has to dispose it as well. Hence I present asynchronous extension methods PickDateAsync and PickDateAndAssignAsync.

With my code you can use this syntax and don’t worry about DatePickerDialog disposal:

EditText et1 = FindViewById<EditText>(Resource.Id.editText1);
await et1.PickDateAndAssignAsync();

There is also an overload that accepts an instance of CancellationToken. Here are the methods:

public static class DatePickerExtension
{
    public static Task<DateTime> PickDateAsync(this EditText dateEdit)
    {
        return dateEdit.PickDateAsync(CancellationToken.None);
    }
    public static Task<DateTime> PickDateAsync(this EditText dateEdit, CancellationToken ct)
    {
        TaskCompletionSource<DateTime> tsc = new TaskCompletionSource<DateTime>();
        DatePickerDialog picker = null;
        DateTime current;
        if (!DateTime.TryParse(dateEdit.Text, out current))
            current = DateTime.Now;
        picker = new DatePickerDialog(dateEdit.Context, (sender, e) =>
        {
            if (tsc != null)
            {
                if (ct.IsCancellationRequested)
                {
                    tsc.SetCanceled();
                }
                else
                {
                    tsc.SetResult(e.Date);
                }
                tsc = null;
                picker.Dispose();
            }
        }, current.Year,current.Month-1,current.Day);
        picker.Show();
        return tsc.Task;
    }

    public static Task PickDateAndAssignAsync(this EditText dateEdit)
    {
        return dateEdit.PickDateAndAssignAsync(CancellationToken.None);
    }
    public static async Task PickDateAndAssignAsync(this EditText dateEdit, CancellationToken ct)
    {
        DateTime date = await dateEdit.PickDateAsync(ct);
        if (!ct.IsCancellationRequested)
        {
            dateEdit.Text = date.ToString("d");
        }
    }
}
Enjoy awesome asynchronous C#/.net support.

Android activity life cycle and IoC

I was recently working on an Android (Xamarin, .net) application based on MvvmCross framework. Actually not just an Android app since it could be ported quite easily to other platforms, such as Windows Phone 8 or IPhone. Anyway, I was using inversion of control principle in a slightly incorrect way and thus done a mistake which revealed only a while after the deployment.

Here are the symptoms: Application would cold start fine, would resume fine when resume was done within reasonable time (no idea, depends on the device, in my case could be hours and it would work perfectly) but it wouldn’t resume well if the timespan was too much (i.e. a day or several hours). Instead of displaying the activity content it was just an actionbar with title without any content of menuitems.

By looking at android’s log on the device itself it was clear that there were problems with IoC resolve method. It yielded an “Object reference null” type of exception. I was resolving the reference within activity’s constructor. Odd error, since MvvmCross is supposed to trigger IoC registration  before the first activity is run. But somehow it wasn’t. I’ve mentioned that to Stuart (@slodge, man behind MvvmCross) and he instantly pointed to the mistake I made – I neglected the Android activity’s lifecycle. I immediately understood my mistake: I am used to put IoC references within constructors as arguments, which is mostly fine. Except when it comes to Android activities. The thing is that the entry point of a suspended application (with activity destroyed) is the activity itself, more precisely, its constructor. MvvmCross does trigger the IoC registration method correcly, but, of course, only after the activity is created and hence I was having errors in this particular situation.

The solution is fairly simple – move IoC resolving within OnCreate method, not sooner – that’s the point where you can be certain that MvvmCross initialization is done.

Before:

public abstract class SomeClass<T> : Activity
{
    protected readonly IFragmentPresenter fragmentPresenter;

    public MvxActivityFragmentHost(): this(Mvx.Resolve<IFragmentPresenter>())
    {}

    public MvxActivityFragmentHost(IFragmentPresenter fragmentPresenter)
    {
        this.fragmentPresenter= fragmentPresenter;
    }
    ...
}

after

public abstract class SomeClass<T> : Activity
{
    protected IFragmentPresenter fragmentPresenter;

    protected override void OnCreate (Bundle bundle)
    {
        base.OnCreate (bundle);
        fragmentPresenter = Mvx.Resolve<IFragmentPresenter>();
    }
    ...
}

This change did the trick. A bit more work to inject the mock reference when testing but not a big deal.

Now, if you followed the post you might be asking, why the heck does application cold starts just fine, since it should get the same error. The explanation is rather simple – I am using a splashscreen activity when application cold starts. This one doesn’t have any IoC resolving involved at all, but it does initialize MvvmCross. So when it gets to the my problematic activity, the IoC is already in place.

Now, there you have it. Respect the Android activity lifecycle otherwise it will bit you.

Poor man’s performance profiling

If you have been doing development with Xamarin on Android you have probably noticed the total absence of any profiler, there is not even a decent method to get the high resolution time. Sure, there is Environment.TickCount but the resolution is at best in milliseconds. Pretty useless for performance profiling.

Rarely people use performance profilers on the desktop. Mostly because their applications don’t have complicated stuff and the modern CPUs are hiding most of the non performing code. However mobile devices are far more delicate and have less CPU power, less RAM, less resources in general. Thus slow code is much more notable and visible to end users. There is no better way to profile your code with a performance profiler. Just take a look at RedGate’s ANTS Performance profiler. Unfortunately there are no such tools for Xamarin Android platform even though mobile code should be really optimized.

I present  my solution for getting some useable metrics from your code (the code you have sources for). The code I’ve written was used for MvvmCross performance profiling hence it slightly relies on it (logging, IoC) however it can be easily made standalone if necessary.

Getting high resolution time

Java has java.lang.System.nanoTime() method that returns the highest resolution time available on Android. Xamarin doesn’t provide it through .net, you have to write a wrapper by yourself using java reflection.

public static class JavaLangSystem
{
    static IntPtr class_ref;
    static IntPtr id_nanoTime;
    public readonly static long Avg;

    static JavaLangSystem()
    {
        class_ref = JNIEnv.FindClass("java/lang/System");
        id_nanoTime = JNIEnv.GetStaticMethodID(class_ref, "nanoTime", "()J");

        for (int i = 0; i < 10; i++)
        {
            NanoTime();
        }

        long start = NanoTime();
        for (int i = 0; i < 1000; i++)
        {
            NanoTime();
        }
        Avg = (NanoTime() - start) / 1000;
MvxTrace.TaggedTrace("metrics", "Avg NanoTime reflection is {0}", Avg); } [Register("nanoTime", "()J", "")] public static long NanoTime() { return JNIEnv.CallStaticLongMethod(class_ref, id_nanoTime); } }

Note that I do some calibration in static constructor because of reflection the call to nanoTime() itself consumes some time. I store the average call time into a static variable Avg that I'll later use.

Accessing high resolution timer through IoC

First part is to create an interface

public interface IHighResolution
{
    long Ticks { get; }
    long Avg { get; }
}

then implement it

public class HighResolution: IHighResolution
{

    #region IHighResolution Members

    public long Ticks
    {
        get { return JavaLangSystem.NanoTime(); }
    }

    public long Avg
    {
        get { return JavaLangSystem.Avg; }
    }

    #endregion
}

and finally register it to IoC provider.

protected override IMvxApplication CreateApp()
{
    Mvx.RegisterType<IHighResolution, HighResolution>();
    return new App();
}

I register it in MvxAndroidSetup derived class (MvvmCross initialization) but if you are not using MvvmCross feel free to register it with IoC provider of your choice on some other initialization place.

This separation comes specially handy if you are to measure PCL assemblies where nanoTime() isn’t accessible.

 

Define class that will store a single measurement

[DebuggerDisplay("{Name} in {Ticks}")]
public class PerfMeasurement
{
    public string Name { get; set; }
    public List<PerfMeasurement> Children;
    public long Ticks { get; set; }

    public int AllChildren
    {
        get
        {
            if (Children == null || Children.Count == 0)
                return 0;
            else
            {
                int sum =0;
                foreach (PerfMeasurement m in Children)
                {
                    sum += 1 + m.AllChildren;
                }
                return sum;
            }
        }
    }
}

There are two interesting features here. First is Children field which holds nested measurements. And the other is AllChildren property that recursively counts all children.

The main measurement class

public static class Metrics
{
    private static readonly IHighResolution highresolution;
    private static readonly long twoAvg;
    
    public static List<PerfMeasurement> RootData { get; private set; }
    private static Stack<PerfMeasurement> stack;
    //         private static int counter;
    
    static Metrics()
    {
        RootData = new List<PerfMeasurement>(100000);
        stack = new Stack<PerfMeasurement>();
        highresolution = Mvx.Resolve<IHighResolution>();
        twoAvg = highresolution.Avg * 2;
    }
    
    public static PerfMeasurement Push(string name)
    {
        PerfMeasurement head;
        if (stack.Count == 0)
        {
            head = new PerfMeasurement { Name = name };
            RootData.Add(head);
        }
        else
        {
            PerfMeasurement previous = stack.Peek();
            head = new PerfMeasurement { Name = name };
            if (previous.Children == null)
                previous.Children = new List<PerfMeasurement>();
            previous.Children.Add(head);
        }
        stack.Push(head);
        return head;
    }
    
    public static void Pull()
    {
        stack.Pop();
        if (stack.Count == 0)
        {
            PerfMeasurement m = RootData[RootData.Count - 1];
            OffsetParents(m);
            Print(m);
        }
    }
    
    private static void OffsetParents(PerfMeasurement m)
    {
        m.Ticks -= m.AllChildren * twoAvg;
        if (m.Children != null)
        {
            foreach (PerfMeasurement child in m.Children)
                OffsetParents(child);
        }
    }
    
    public static void Print(PerfMeasurement metric)
    {
        StringBuilder sb = new StringBuilder();
        Print(metric, sb, 0);
        MvxTrace.TaggedTrace("metrics", sb.ToString());
    }
    
    public static void Print(PerfMeasurement metric, StringBuilder sb, int depth)
    {
        string prepend = new string(' ', depth * 4);
        sb.AppendLine(string.Format("{0}{1} took {2:#,##0}", prepend, metric.Name, metric.Ticks));
        if (metric.Children != null && metric.Children.Count > 0)
        {
            foreach (PerfMeasurement child in metric.Children)
            Print(child, sb, depth + 1);
        }
    }
}

This class acts like a Stack for measurement items defined in earlier one. When item at the root level is pulled it outputs the results of the whole hierarchy linked to it into the (MvvmCross) logging mechanism (Print methods). But before doing that it recursively subtracts the nanoTime() invocation of all children (OffsetParents - for each children it assumes nanoTime() took two average invocations – hence the static field twoAvg).

That’s all we need. However there is one step that will make measurement a bit easier and more clean.

 

Making it easier to use Metrics with a helper class

public class MeasurePerf : IDisposable
{
    private static readonly IHighResolution highresolution;

    private long start;
    private PerfMeasurement m;

    static MeasurePerf()
    {
        highresolution = Mvx.Resolve<IHighResolution>();
    }

    public MeasurePerf(string name)
    {
        m = Metrics.Push(name);
        this.start = highresolution.Ticks;
        
    }

    public void Dispose()
    {
        m.Ticks += highresolution.Ticks - start - highresolution.Avg;
        Metrics.Pull();
    }
}

This class is intended as a wrapper around measured code using using keyword. Measurement looks like:

using (new MeasurePerf("Your comment here"))
{
    // your code here
    // nesting measuring is perfectly fine
}

Here is a sample output I’ve been looking at:

profiler_results

I highlighted the root item. All items are showing their total time (children included). Note the negative numbers. That happens because this kind of measurement isn’t accurate at all (remember, I am subtracting twoAvgs). However it gives you at least some insight of what code is slow and which child is guilty.

So, that’s it. Until Xamarin gives us profilers there is no better way AFAIK. Unfortunately. There is one thing you can do, though. You can tell Xamarin that we need profilers. Perhaps through my uservoice suggestion.

A week of impressions of developing for Android using Xamarin & MvvmCross

Occasionally I watch road bicycling and it happens that I started following Vuelta 2013. Of course I downloaded the official application for Android as well - to keep an eye on standings. The poor quality of the Android application bothered me a bit. Both the lack of data and poor UI. Most notably I really found it hard to see where my favorite bicyclists are standing.

This triggered a well known feeling in me - I have to create my own Android application instead. For quite some time I was eying Android development but so far I didn't have a proper motivation.Armed with Xamarin and MvvmCross I dived in. I had almost no experience with Android OS development, very little of Xamarin and none of MvvmCross. The goal was to create a MVVM based application that could leverage the common code along different mobile platforms though the current state is Android only application. I could create a version for iOS and Windows Phone 8 as well, I guess, but I don't have a Mac (required to build for iOS) nor I want to loose a ton of time to enable Windows Phone development environment for a free application (which is a shame because WP8 development doesn't look bad at all). Perhaps sometime.

The application itself is available for free through Google Play. Go, get it, while it is still actual.

About Xamarin

What they have done is simply amazing. Porting Mono (.net) stack to mobile platforms that is. Including the latest crazy useful async/await.This gives a .net developer an option to provide common code base for Windows RT, desktop Windows, Windows Phone, Android and iOS and to unleash the .net on platforms MS didn't want you to. The community is there. But it comes with some quirks. Here are some major ones I found while developing with Visual Studio 2012:

  • debugger is often slow. Sometimes it takes quite a lot of tenths of seconds to be able to inspect variables at a breakpoint
  • async/await debugger breakpoints stop at random lines of code and often "Step Over" or "Step Into" means "Continue running"
  • Portable Class Library support is still a problem (most notably, VS Android projects can't reference PCL assemblies while Xamarin IDE intellisense goes beserk on PCLs)
  • no profilers available (performance, memory) for Android. These are insanely important for mobile devices. Vote here.
  • price for Indie developers (small shops) might be high

I am not exactly sure whether some of these problems might be attributed to VS or Xamarin integration. Anyway, none of these is a showstopper and I am sure they'll be addressed.

About MvvmCross

This framework is an excellent open source MVVM starting point for cross platform .net mobile development. @slodge. the author, has done and is still doing an insane job. Not just by creating the framework but he is all over the Internet answering questions and writing (well, mostly recording) documentation and samples. That said there are some problems with MvvmCross:

  • huge framework, takes time to grasp
  • I miss better fundamentals description (i.e how DataContext is transferred to children)
  • sometimes slow (i.e. startup time, ListView bindings). NOTE: since there is no performance profiler available I couldn't exactly determine why it acts slowly sometimes. Could be Xamarin, could be MvvmCross or Android or my code.
  • some error messages could be better (i.e. suggesting you a solution instead of just reporting errors)

But hey, it is open source and I plan to contribute if time permits.

About Android

It is not hard to learn the basics but it has plenty of small issues and traps one has to be aware of. The fragmentation doesn't help either nor does java stack but overall it isn't that big of an issue.

Then there are Intel Android x86 images which are used if you want to run the emulator. (Forget about ARM ones due to the slowness). Intel Android x86 v17 image has a quirk that logs messages like nuts making log window pretty much useless. Then there is the v18 image that fixed overlogging issue but introduced a new one. It'd throw "can't resolve host" when using HttpClient 99% of the time. This issue might be attributed to Xamarin though as its browser doesn't exhibit same problems.

Google Play store publishing

Straightforward, no issues. Wait, there is a potential problem. If you want to publish an app on Google Play store you have to comply to US laws, most notably they warn you of using encryption. I wonder why (rhetorical).

So, these are my impressions, after a week of development. Note that I mostly listed problems I've encountered not described the (bright points of) products in details.

Feel free to feedback me.