Since version 4.2 of Xamarin for Visual Studio the Xamarin.Android has become very slow, sometimes lasting up to five minutes depending on the machine. Tired of wasting so much time waiting for the build, I decided to search for a solution although what I found is something more of a hack than a workaround.
Analyzing the problem
On my machine it last almost two minutes on average just building the Android problem, after investigating a while I found the problem is in the GetAdditionalResourcesFromAssemblies task which is taking a large amount of time, 68 seconds in this case.
This task is defined in the Xamarin.Android.Build.Tasks.dll that comes with Xamarin. And the culprit of the problem is the method Xamarin.Android.Tasks.GetAdditionalResourcesFromAssemblies.IsValidDownload which seems to be rehashing the packages in each build.
NOTE: This issue has been fixed in the 4.3 betas of Xamarin, the build is definitely faster and lasts 30 seconds or less. But in my case these betas throw me a runtime exception so I kept using this method.
Hacking the problem away
In order to fix the problem we're gonna have to modify the Xamarin.Android.Tasks.dll to avoid rehashing the downloaded packages.
First download the open source .NET decompiler ILSpy and the IL editor Reflexil.
Once downloaded extract both packages to the same directory as Reflexil is a plugin for ILSpy and needs to be in the same directory to be loaded.
Open ILSpy and load the Xamarin.Android.Tasks dll which is located on C:\Program Files (x86)\MSBuild\Xamarin\Android\Xamarin.Android.Build.Tasks.dll.
Expand the Xamarin.Android.Build.Tasks tree and locate the Xamarin.Android.Tasks node.
Then locate the GetAdditionalResourcesFromAssemblies node and select the IsValidDownload method.
Once located, click on the gear icon on the upper bar to see the IL code for the method:
Don't get scared by the code, you just know that wee need to modify the line 3 which is where the if-else jump happens based on the value of the 'result' variable. To do that, select the line number 3, right click and select "Edit...".
When you click Edit a box will popup and there we will change the Operand from line 7 to line 4.
So select the line 4 from the select and click update.
The IL code will now look like this:
What we did is basically to tell the compiler to exit the method whatever the result of the comparison is.
Now, select the first node of the dll, right click and select Verify
If somehow we broke the assembly, or it has some kind of protection we will receive a window stating that wee need to fix the assembly.
And if all goes ok then we will receive a success message:
Saving changes and testing the hack
Close the dialog then right click the the dll node and then "Save as". If you still have Visual Studio open, now it's the time to close it.
Go to C:\Program Files (x86)\MSBuild\Xamarin\Android and make a backup of the Xamarin.Android.Build.Tasks.dll file. In this case I changed its extension to .bakdll.
Now copy our modified dll.
Open Visual Studio and build a Xamarin.Android project, you should notice a noticeable difference in the build time. In my case the build reduced from almost two minutes to 34 second, but YMMV (Your Mileage May Vary).
As you see, my build time is roughly 50% percent faster, I heard some people reduced the time from 7 down to 2 minutes (which is still much time, in my opinion).
Note that in Xamarin 4.3 betas these issues seem to be resolved, so try them out before doing this hack.
In my case I receive an error on application startup saying "Could not load Microsoft.Build.Framework during startup registration", if the same happens to you then you can use this method while a workaround is found.