Wednesday, April 16, 2014

HttpClient is unstable using Xamarin.Android

This post is about stabilizing the HttpClient. There is really no new information in this post of my behalf. It's more a summary of what's out there.

Short version, if HttpClient hangs for you on android, use ModernHttpClient, also available in the Xamarin Component Store for free.

To get async support for the HttpClient you need to install the Microsoft HTTP client libraries. Current version is 2.2.18 and it's available from Nuget under the id Microsoft.Net.Http.

This will give you a nice way of downloading stuff async.

var content = await client.GetStringAsync(relativeUrl);

However, at the current date, the HttpClient's async support for Xamarin.Android is unstable. I have not encountered any problems for iOS but for Android it often hangs and times out giving you a TaskCancelled-exception.

To be fair to Microsoft, there is no written support for Android or iOS. Hopefully they'll make a more stable version in the future.

Usually you'll wrap all this in a container and all that fancy stuff, but for the sake of simplicity I keep the code clean.

The solution to your problem is...

Use ModernHttpClient

The solution is to install the ModernHttpClient component from Xamarin Component Store and initiate the HttpClient using a better HttpMessageHandler.

For android it looks like this

var client = new HttpClient(new OkHttpNetworkHandler());

Always dispose your client

This is a very important thing. Always dispose the client on Android or it might lock up your entire http stack. (not verified, only experienced). The simplest way of doing so is to wrap it in a using statement.

using (var client = new HttpClient(new OkHttpNetworkHandler()))
{
    // Setup the client
    ....

    // Make the call
    var content = await client.GetStringAsync(theUrl);
}

Resources



3 comments:

  1. I also noticed this while working on a project for Android a week back. I'm glad to see I'm not the only one!

    I'm curious how to implement ModernHttpClient in a PCL. That's what I loved about the HttpClient, I was able to just call my exposed methods from iOS and/or Android and it worked (except when it didn't for Android). But I can't seem to figure out how to get ModernHttpClient to work since it uses different libraries for iOS and Android. Any code examples would be very helpful!

    ReplyDelete
    Replies
    1. What you need is Inversion of Control to inject the HttpMessageHandler into your pcl. I've written a blog post about mobile architecture at http://johankson.blogspot.se/2014/04/the-outline-of-mobile-architeture-using.html

      Delete
  2. Oh, and I'd be happy to write a post about IoC if you'd be interested. Of course, chances are that you'll never see this comment since you made an anonymous post. :)

    ReplyDelete