Xamarin-android: Aapt and Aapt2 MSBuild tasks do not yet use -G and --proguard options to help generate rules when ProGuard or R8 is enabled

Created on 16 Sep 2019  路  6Comments  路  Source: xamarin/xamarin-android

Previous related reports:

Steps to reproduce

  1. Create a new Single View Android app.
  2. Set Code shrinker to ProGuard or r8 in the Android Options section of the project properties for the Release configuration.
  3. Set the Compile using Android version: (Target Framework) to Android 8.1 (Oreo) as a way to avoid the missing proguard.txt files in the monoandroid90 target framework directories in the Xamarin.Android.Support NuGet packages.
  4. Build and run the app in the Release configuration on an emulator or device.

Example project: SingleViewAndroidApp1.zip

Expected behaviors

In a Gradle build in Android Studio for a matching project, some important types are preserved by app\build\intermediates\proguard-rules\release\aapt_rules.txt. Based on those results, I believe the expected behaviors are:

  • The Aapt2 task passes the --proguard aapt_rules.txt option to aapt2.exe and then passes the resulting aapt_rules.txt file to ProGuard or R8.

    (Or for aapt, the Aapt task passes the -G aapt_rules.txt option to aapt.exe and then passes the resulting aapt_rules.txt file to ProGuard or R8.)

  • The app runs without error.

Actual behaviors

  • The Aapt2 task does not pass the --proguard option to aapt2.exe, and the Aapt task does not pass the -G option to aapt.exe.

  • The app exits during startup because some required types are missing:

    UNHANDLED EXCEPTION:
    Java.Lang.Exception: Binary XML file line #17: Binary XML file line #17: Error inflating class android.support.v7.widget.FitWindowsLinearLayout ---> Java.Lang.Exception: Binary XML file line #17: Error inflating class android.support.v7.widget.FitWindowsLinearLayout ---> Java.Lang.ClassNotFoundException: Didn't find class "android.support.v7.widget.FitWindowsLinearLayout" on path: DexPathList[[zip file "/system/framework/org.apache.http.legacy.boot.jar", zip file "/data/app/com.companyname.SingleViewAndroidApp1-mH2uq3zIMPtg74LEwholzQ==/base.apk"],nativeLibraryDirectories=[/data/app/com.companyname.SingleViewAndroidApp1-mH2uq3zIMPtg74LEwholzQ==/lib/arm64, /data/app/com.companyname.SingleViewAndroidApp1-mH2uq3zIMPtg74LEwholzQ==/base.apk!/lib/arm64-v8a, /system/lib64]]
       --- End of inner exception stack trace ---
       --- End of inner exception stack trace ---
      at Java.Interop.JniEnvironment+InstanceMethods.CallNonvirtualVoidMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniObjectReference type, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x00089] in <a4799c6c501b49678cf6198cb1aef16d>:0 
      at Java.Interop.JniPeerMembers+JniInstanceMethods.InvokeVirtualVoidMethod (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) [0x0005d] in <a4799c6c501b49678cf6198cb1aef16d>:0 
      at Android.App.Activity.SetContentView (System.Int32 layoutResID) [0x00022] in <79b6bab2d7a34df8b5739e028c597831>:0 
      at SingleViewAndroidApp1.MainActivity.OnCreate (Android.OS.Bundle savedInstanceState) [0x0000e] in <4106ae493f094976aff9acf26162ea25>:0 
      at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_savedInstanceState) [0x00011] in <79b6bab2d7a34df8b5739e028c597831>:0 
      at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.3(intptr,intptr,intptr)
    

Manual workaround, proof of concept

  1. If the project has Use incremental Android packaging system (aapt2) enabled, add the following lines to the .csproj file:

    <PropertyGroup>
      <AndroidAapt2LinkExtraArgs>--proguard aapt_rules.txt $(AndroidAapt2LinkExtraArgs)</AndroidAapt2LinkExtraArgs>
    </PropertyGroup>
    

    Or if the project does not have the incremental Android packaging system enabled, add the following lines instead:

    <PropertyGroup>
      <AndroidResgenExtraArgs>-G aapt_rules.txt $(AndroidResgenExtraArgs)</AndroidResgenExtraArgs>
    </PropertyGroup>
    
  2. Build and run the app again to generate the aapt_rules.txt file in the project directory.

  3. Add the new aapt_rules.txt file to project in the Solution Explorer, and set the Build Action to ProguardConfiguration.

  4. Remove the lines from the .csproj that were added in step 1 (to keep the generated aapt_fules.txt under careful manual control for this proof of concept).

  5. Clean, rebuild, and rerun the app.

The app now launches successfully.

Version information

This behavior exists in Visual Studio 2019 version 16.4 Int Preview with Xamarin.Android 10.0.0.40.

This behavior has been the same for the built-in template projects since back to at least Visual Studio 2019 version 16.1 with Xamarin.Android 9.3.0.23.

App+Library Build

Most helpful comment

I wonder if the Xamarin team could place a higher priority on this bug. Xamarin app are already really large in terms of App Store size and essentially this means Proguard can't be used at all. With upcoming app store changes around the use of bundles etc all this sort of stuff is going to be critical.

All 6 comments

I'd be happy to take a try setting up a PR to add these options to the Aapt and Aapt2 tasks when I get a chance. But anyone else feel free to take care of it before then if you like.

I wonder if the Xamarin team could place a higher priority on this bug. Xamarin app are already really large in terms of App Store size and essentially this means Proguard can't be used at all. With upcoming app store changes around the use of bundles etc all this sort of stuff is going to be critical.

I should probably add a few words to my previous comment for clarity. Instead of "anyone else," I should have said "anyone else on the team." I suspect someone else on the team might beat me to adding this functionality.

Release status update

A new Preview version has now been published on Windows that includes the fix for this item. The fix is not yet included in a Release version. I will update this item again when a Release version is available that includes the fix.

The fix is not yet available on macOS. I will update this item again when a Preview version with the fix is available on macOS.

Fix included in Xamarin.Android 10.2.100.7

Fix included on Windows in Visual Studio 2019 version 16.6 Preview 1. To try the Preview version that includes the fix, check for the latest updates in Visual Studio Preview.

Fix not yet available on macOS.

Release status update

A new Preview version has now been published on macOS that includes the fix for this item. The fix is not yet included in a Release version. I will update this again when a Release version is available that includes the fix.

Fix included in Xamarin.Android 10.3.0.33.

Fix included on macOS in Visual Studio 2019 for Mac version 8.6 Preview 1. To try the Preview version that includes the fix, check for the latest updates on the Preview updater channel.

(Fix also included on Windows in Visual Studio 2019 version 16.6 Preview 1 and higher. To try the Preview version that includes the fix, check for the latest updates in Visual Studio Preview.)

Release status update

A new Release version has now been published that includes the fix for this item.

Fix included in Xamarin.Android 10.3.1.0.

Fix included on Windows in Visual Studio 2019 version 16.6. To get the new version that includes the fix, check for the latest updates or install the latest version from https://visualstudio.microsoft.com/downloads/.

Fix included on macOS in Visual Studio 2019 for Mac version 8.6. To get the new version that includes the fix, check for the latest updates on the Stable updater channel.

Was this page helpful?
0 / 5 - 0 ratings