Recently I decided to add Google Analytics to my app. Whilst this is a necessity in order to understand users paths through the app, adding the Android version of the SDK was not as easy as it could have been.
To begin with I decided to add the SDK as a component from the Xamarin store. This is simple enough to do, however when i added the SDK it dragged in a whole bunch of dependencies that i did not need.
Unfortunately for me, this brought me over the Dex limit for my apk (by around double the limit). Because of this I did some research and all answers told me to enable Proguard. Proguard is a tool that will strip out any code and methods that are not used, reducing the APK in size and not including any of the 20 new dependencies Google Analytics decided to drag in. Just the bits of code that I actually use.
So how hard can enabling Proguard in Xamarin.Android be?
Turns out pretty hard! below are the steps I went through to get it working and what I learnt along the way.
First of all if you are targeting Android 7 / N / API 24 / Whatever other name Google decides to make up for Android versions, Then you will need to swap out the version of Proguard that is used. This can be done by following these steps:
- Download the latest version of Proguard from here
- Find where your Android SDK is installed. On my mac I seem to have two installations. One for the native version of Android that Android Studio uses. Another for the version of Android that Xamarin uses. Because i’m doing this for a Xamarin based build, i’ll use the location for that, which in this case is something like “/Users/yourusername/Library/Developer/Xamarin/android-sdk-macosx/tools/proguard”
- Swap out the old version of Proguard, with the new one. To do this rename the current folder to something like “Proguard-pointless” and copy your new one into the tools folder. Be sure to rename the folder for the new version to just be “proguard”.
- Make sure that any configuration files are also copied across into the new Proguard folder. For me this was proguard-android-optimize.txt, proguard-android.txt, and proguard-project.txt.
Now that you have the right version, you’ll need to enable Proguard for your Android project. This can be done by right clicking on your .Droid project in Xamarin studio and selecting options. Once the panel opens find Android Build underneath the Build section, select your configuration to be Release, and select the Enable Proguard checkbox. See the screenshot below for reference.
Once you have configured Proguard for your project, ensure you are building in Release mode as the target in Xamarin Studio. Try your hand at a build and see what happens. In my case I got warnings to do with Google Maps, Facebook advertising, and OkIo. To suppress these warnings you will need to add your own Proguard configuration file. To do this follow the steps below
- Add a new file to the root of your Droid project called proguard.cfg
- Because Xamarin is smart, it saves this new file in UTF-8 with BOM, you will need to change this. Open something like Visual Studio Code and re save the file with a UTF-8 encoding. This is required because Proguard will not read the file unless it is in UTF-8 encoding.
- In Xamarin studio, right click on the file and select properties. For Build Action, select ProguardConfiguration. See the screenshot below for reference.
- Add relevant keep or dontwarn clauses to the file, see below for an example of code that keeps google maps files and ignores OkIo warnings.
-keep class com.google.android.gms.**
-keep class com.facebook.ads.internal.adapters.**
Once you have done those steps, try a build once again. Hopefully this time it will be more successful. If it is not successful, check your build output and see what warnings and notes Proguard is giving you. From this stage it is a matter of identifying what modifications you need to make to your custom Proguard file, once that works the build will be successful.
As you can see, it’s not that easy to add Proguard to your Xamarin Android project. Hopefully this will help anybody else that runs into the need to do this. Additionally hopefully Xamarin make this process easier and clearer for developers in the future.