Briefly, it appears “R8” Code Shrinking causes an Android App to crash if using AdMob (even latest version 118.3.0).
The scenario is, using Visual Studio 2019 you’ve just added AdMob to your MonoGame Android project…
You’ve added these updates to the AppManifest.xml:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> ... <application ...> <!-- TODO: Replace with your real AdMob app ID --> <meta-data android:name="com.google.android.gms.ads.APPLICATION_ID" android:value="ca-app-pub-3940256099942544~3347511713" /> </application>
You’ve signed your app.
You’ve deployed to a device in Debug mode. Successfully.
You then deploy in Release mode with “R8” code shrinking enabled (“ProGuard” is no longer supported, apparently) . Your app crashes with no message.
Hmmmm. You then go back to Debug configuration and enable “R8” code shrinking on that. The app still crashes but now you see the error message starting:
Java.Lang.RuntimeException: 'Unable to get provider com.google.android.gms.ads.MobileAdsInitProvider: java.lang.ClassNotFoundException: Didn't find class "com.google.android.gms.ads.MobileAdsInitProvider" on path: DexPathList[[zip file "/system/framework/org.apache.http.legacy.boot.jar", zip file "/data/app/
…followed by info particular to your app name.
I’ve tried google and generic “Android questions” on stackoverflow such as these:
But commonly they’re either not answered or result in “Did you manage to solve this?” messages.
One workaround, of course, is to not use ANY code shrinking since ProGuard is not allowed and “R8” causes your app to crash.
But why? Well, another workaround I’ve found is to specify that the Linker skips the assembly containing the “.MobileAdsInitProvider” class namely the, “Xamarin.GooglePlayServices.Ads.Lite” assembly. So adding:
to the “Skip Linking Assemblies” also works around the problem.
Being unfamiliar I read here: https://docs.telerik.com/devtools/xamarin/knowledge-base/common-understanding-ui-for-xamarin-and-linker-behavior
As the linker is a static tool, it can not plan for or include types and methods that are called through reflection, or dynamically instantiated. In short, if that type is not explicitly referenced in your project code, it will get removed by the linker.
So my understanding is that reflection or dynamic (Java interop?) code is being used in the AdMob implementation of “Xamarin.GooglePlayServices.Ads.Lite” (and maybe other dependancies too, maybe there are further problems waiting down the road by doing this?) and the linker is stripping them out if any “code shrinking” is enabled.
I’m unsure if this is correct though as it seems such a mainstream thing yet there there seems very little public knowledge, instruction or discussion about it, other than “Did you manage to solve this?”, unless I’m just missing it completely.
Is anyone here able to confirm or deny any of this? Are there better solutions? Is Code Shrinking just bad form and something to be avoided when using any interop?