Xamarin.Android projects hit the multidex limit much quicker than Android Studio projects

*Description:

I've been investigating a potential issue with regards to the multidex limit in Xamarin.Android projects versus Android Studio projects.

What I've noticed is that Android Studio projects seem to handle many more library references than the Xamarin.Android counterpart.

It seems that the `CompileToDalvik` MSBuild task that invokes dx.jar causes Xamarin.Android projects to reach the multidex limit faster than the Android Studio counterpart.

*Reproduction:

For my samples, I took a blank Xamarin.Android project and a blank Android Studio project.

I then added as many Android Support Libraries as I could until I hit the dex limit. Here is what I found out:

1. Xamarin.Android was only able to hold 24 references to support libraries before hitting the dex limit(Libraries have different dex counts, but using this number as reference to Android Studio):

<?xml version="1.0" encoding="utf-8"?>
<packages>

  <package id="Xamarin.Android.Support.Animated.Vector.Drawable" version="25.1.1" targetFramework="monoandroid71" />
  <package id="Xamarin.Android.Support.Compat" version="25.1.1" targetFramework="monoandroid71" />
  <package id="Xamarin.Android.Support.Core.UI" version="25.1.1" targetFramework="monoandroid71" />
  <package id="Xamarin.Android.Support.Core.Utils" version="25.1.1" targetFramework="monoandroid71" />
  <package id="Xamarin.Android.Support.CustomTabs" version="25.1.1" targetFramework="monoandroid71" />
  <package id="Xamarin.Android.Support.Design" version="25.1.1" targetFramework="monoandroid71" />
  <package id="Xamarin.Android.Support.Exif" version="25.1.1" targetFramework="monoandroid71" />
  <package id="Xamarin.Android.Support.Fragment" version="25.1.1" targetFramework="monoandroid71" />
  <package id="Xamarin.Android.Support.Media.Compat" version="25.1.1" targetFramework="monoandroid71" />
  <package id="Xamarin.Android.Support.Percent" version="25.1.1" targetFramework="monoandroid71" />
  <package id="Xamarin.Android.Support.Recommendation" version="25.1.1" targetFramework="monoandroid71" />
  <package id="Xamarin.Android.Support.Transition" version="25.1.1" targetFramework="monoandroid71" />
  <package id="Xamarin.Android.Support.v13" version="25.1.1" targetFramework="monoandroid71" />
  <package id="Xamarin.Android.Support.v14.Preference" version="25.1.1" targetFramework="monoandroid71" />
  <package id="Xamarin.Android.Support.v4" version="25.1.1" targetFramework="monoandroid71" />
  <package id="Xamarin.Android.Support.v7.AppCompat" version="25.1.1" targetFramework="monoandroid71" />
  <package id="Xamarin.Android.Support.v7.CardView" version="25.1.1" targetFramework="monoandroid71" />
  <package id="Xamarin.Android.Support.v7.GridLayout" version="25.1.1" targetFramework="monoandroid71" />
  <package id="Xamarin.Android.Support.v7.MediaRouter" version="25.1.1" targetFramework="monoandroid71" />
  <package id="Xamarin.Android.Support.v7.Palette" version="25.1.1" targetFramework="monoandroid71" />
  <package id="Xamarin.Android.Support.v7.Preference" version="25.1.1" targetFramework="monoandroid71" />
  <package id="Xamarin.Android.Support.v7.RecyclerView" version="25.1.1" targetFramework="monoandroid71" />
  <package id="Xamarin.Android.Support.Vector.Drawable" version="25.1.1" targetFramework="monoandroid71" />
  <package id="Xamarin.Build.Download" version="0.4.3" targetFramework="monoandroid71" />

</packages>

With these packages all added, dx.jar will fail stating that multidex needs to be enabled:

https://gist.github.com/JonDouglas/73a2562e5a658ed41885904e3385c564

Thus it claims that 67288 references are being used here from the output of dx.jar. The other strange observation here is that some of these libraries that have very different counts end up becoming the same number. You will see a repeated "2422" as a count for many libraries when the actual .jar differs.

2. Android Studio had no problem with the same packages, and it didn't even get close to the dex limit:

    compile 'com.android.support:support-compat:25.3.1'
    compile 'com.android.support:support-core-ui:25.3.1'
    compile 'com.android.support:support-core-utils:25.3.1'
    compile 'com.android.support:customtabs:25.3.1'
    compile 'com.android.support:design:25.3.1'
    compile 'com.android.support:exifinterface:25.3.1'
    compile 'com.android.support:support-fragment:25.3.1'
    compile 'com.android.support:percent:25.3.1'
    compile 'com.android.support:support-media-compat:25.3.1'
    compile 'com.android.support:support-v4:25.3.1'
    compile 'com.android.support:appcompat-v7:25.3.1'
    compile 'com.android.support:cardview-v7:25.3.1'
    compile 'com.android.support:gridlayout-v7:25.3.1'
    compile 'com.android.support:mediarouter-v7:25.3.1'
    compile 'com.android.support:palette-v7:25.3.1'
    compile 'com.android.support:recyclerview-v7:25.3.1'
    compile 'com.android.support:preference-v7:25.3.1'
    compile 'com.android.support:support-v13:25.3.1'
    compile 'com.android.support:preference-v14:25.3.1'
    compile 'com.android.support:support-annotations:25.3.1'
    compile 'com.android.support:leanback-v17:25.3.1'
    compile 'com.android.support:recommendation:25.3.1'
    compile 'com.android.support:preference-leanback-v17:25.3.1'
    compile 'com.android.support:support-media-compat:25.3.1'
    compile 'com.android.support:support-annotations:25.3.1'

`classes.dex` count: 25966

*Investigation:

However I then investigated each individual `classes.jar` being inputted in the dx.jar command from the gist above and noticed that the counts weren't even close.

https://gist.github.com/JonDouglas/e576a023cfd7f014035e86b0945b3936

This gist shows an output of 21696.

The other fact is that if you remove a couple libraries from NuGet for the Xamarin.Android application and successfully rebuild, the dex count is still around the ~22k count. This isn't even close to the 65,536 limit and thus I suspect something is going on. I haven't been able to figure out what that is quite yet. I even went as far as adding --verbose logging to dx.jar and seeing if it was adding certain libraries multiple times.

https://gist.github.com/JonDouglas/2b5eb5fc3bb2a4a390cf879be1aedbe8

However I did not see anything that quite caught my eye here. My overall suspicions:

1) Something is being added to dx.jar many times to the point of hitting the dex limit
2) Optimization/pre-dexing is different in Android Studio vs. Xamarin.Android
3) The strange number of "2422" for libraries that have different counts seems suspicious

*Version Information:

Microsoft Visual Studio Enterprise 2017
Version 15.1 (26403.0) Release
VisualStudio.15.Release/15.1.0+26403.0
Microsoft .NET Framework
Version 4.6.01586

Installed Version: Enterprise

Xamarin 4.4.0.34 (3f99c5a)
Visual Studio extension to enable development for Xamarin.iOS and Xamarin.Android.

Xamarin.Android SDK 7.2.0.7 (b16fb82)
Xamarin.Android Reference Assemblies and MSBuild support.

Xamarin.iOS and Xamarin.Mac SDK 10.8.0.174 (7656cc6)
Xamarin.iOS and Xamarin.Mac Reference Assemblies and MSBuild support.


Reference: https://bugzilla.xamarin.com/show_bug.cgi?id=55117