Search code examples
androidxamarinxamarin.androidproguardandroid-proguard

How can I ensure that ProGuard keeps all my own classes in Xamarin.Android?


I'm having a problem with ProGuard removing my own classes. I have created a proguard.cfg where I try to specify -keep class for them, but I can only get it working when specifying the classes with their md5 hashed package.

For example, the package name for my application is se.initech.foo, and I have a class in a sub-package Framework, called InfoBox. So I would expect the fully qualified class name to be se.initech.foo.Framework.InfoBox.

But after I compile and package and run ProGuard, in the application output log I can see that it can't find the class md586c878b9e5eee7e17627db5c3cd60647.InfoBox.

And if I add

-keep class md586c878b9e5eee7e17627db5c3cd60647.** { *; }

to my proguard.cfg file, it works. However, if I try to specify the real class name, i.e. se.initech.foo.** or even se.initech.foo.Framwork.InfoBox, it doesn't work.

Is there a way to

a) use the real package name of the classes in proguard.cfg, or

b) find out the hashes beforehand, and not only by inspecting the crashes in the application output log?


Solution

  • Xamarin auto-generates a proguard_xamarin.cfg that includes your project classes (it will be in your obj artifact directory):

    proguard_xamarin.cfg Example:

    ~~~~
    -keep class md52ce486a14f4bcd95899665e9d932190b.** { *; <init>(...); }
    -keepclassmembers class md52ce486a14f4bcd95899665e9d932190b.** { *; <init>(...); }
    ~~~~
    

    It will also create a proguard_project_references.cfg that includes all the Android Callable Wrapper (ACW) classes that your project creates.

    If you do not want to Xamarin to auto-create MD5-based class names, you will need to manually assign a Name via class attributes (~~~~Attribute), i.e.:

    ActivityAttribute Name:

    [Activity(Name = "com.sushhangover.proguarddroid.StackOverflowActivity", Label = "ProGuardDroid", MainLauncher = true, Icon = "@mipmap/icon")]
    

    BroadcastReceiverAttribute Name:

    [BroadcastReceiver(Name = "com.sushhangover.proguarddroid.SOBroadcastReceiver")]
    public class SOBroadcastReceiver : BroadcastReceiver