Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Xamarin.Android.Build.Tasks] Enable 'AndroidLinkResources' for .NET 6 Release Applications #6696

Merged
merged 1 commit into from
Feb 16, 2022

Conversation

dellis1972
Copy link
Contributor

@dellis1972 dellis1972 commented Feb 3, 2022

The current implementation of the RemoveResourceDesignerStep does not
work under .NET 6. This is mostly down to the fact that we didn't
override the require methods to make it work in that environment.

This PR also reworks the RemoveResourceDesignerStep to split some
of the functionality out into a new base class. This new base class will
be used in the future by the Resource Assembly linker step. Since much of
the code is identical.

Apk size difference in a Basic Android Application. This is a single App Head project with no additional libraries or Nuget references.

Size difference in bytes ([*1] apk1 only, [*2] apk2 only):
  -         596 assemblies/assemblies.blob
  -         760 lib/x86/libaot-DotNet6AndroidBasic.dll.so
  -         764 lib/armeabi-v7a/libaot-DotNet6AndroidBasic.dll.so
  -         864 lib/x86_64/libaot-DotNet6AndroidBasic.dll.so
  -       5,032 lib/arm64-v8a/libaot-DotNet6AndroidBasic.dll.so
Summary:
  -         596 Other entries -0.03% (of 2,347,758)
  +           0 Dalvik executables 0.00% (of 333,284)
  -       7,420 Shared libraries -0.03% (of 23,525,172)
  +           0 Package size difference 0.00% (of 11,745,501)

Basic Android Application which references AndroidX. This example includes an App Head project as well as a single Android Library project. Both contain 2-3 AndroidResource items and both reference AndroidX. The Resource.Designer.cs file is 460kb in size.

Size difference in bytes ([*1] apk1 only, [*2] apk2 only):
  -      63,664 lib/x86/libaot-DotNet6AndroidTest.App.dll.so
  -      63,952 lib/x86_64/libaot-DotNet6AndroidTest.App.dll.so
  -      83,900 assemblies/assemblies.blob
  -      84,408 lib/arm64-v8a/libaot-DotNet6AndroidTest.App.dll.so
  -      92,340 lib/armeabi-v7a/libaot-DotNet6AndroidTest.App.dll.so
Summary:
  -      83,900 Other entries -2.83% (of 2,965,109)
  +           0 Dalvik executables 0.00% (of 959,460)
  -     304,364 Shared libraries -1.28% (of 23,781,188)
  -     163,840 Package size difference -1.30% (of 12,620,512)

Basic Maui Application size difference. This is just a standard dotnet new maui app built for the Android platform.

Size difference in bytes ([*1] apk1 only, [*2] apk2 only):
  +          24 lib/arm64-v8a/libaot-Microsoft.Maui.Graphics.dll.so
  -          48 lib/arm64-v8a/libaot-Microsoft.Maui.Controls.Xaml.dll.so
  -         396 lib/armeabi-v7a/libaot-Microsoft.Maui.dll.so
  -         448 lib/arm64-v8a/libaot-Microsoft.Maui.dll.so
  -         536 lib/x86/libaot-Microsoft.Maui.Controls.Compatibility.dll.so
  -         592 lib/x86_64/libaot-Microsoft.Maui.Controls.Compatibility.dll.so
  -         632 lib/armeabi-v7a/libaot-Microsoft.Maui.Controls.dll.so
  -         632 lib/x86/libaot-Microsoft.Maui.Controls.dll.so
  -         720 lib/x86_64/libaot-Microsoft.Maui.Controls.dll.so
  -       4,492 lib/x86/libaot-Microsoft.Maui.dll.so
  -       4,544 lib/x86_64/libaot-Microsoft.Maui.dll.so
  -       4,568 lib/arm64-v8a/libaot-Microsoft.Maui.Controls.Compatibility.dll.so
  -       4,628 lib/armeabi-v7a/libaot-Microsoft.Maui.Controls.Compatibility.dll.so
  -       4,792 lib/arm64-v8a/libaot-Microsoft.Maui.Controls.dll.so
  -      26,676 lib/x86/libaot-BasicMauiApp.dll.so
  -      27,000 lib/x86_64/libaot-BasicMauiApp.dll.so
  -      30,772 lib/armeabi-v7a/libaot-BasicMauiApp.dll.so
  -      31,096 lib/arm64-v8a/libaot-BasicMauiApp.dll.so
  -     124,129 assemblies/assemblies.blob
Summary:
  -     124,129 Other entries -1.18% (of 10,513,973)
  +           0 Dalvik executables 0.00% (of 6,459,432)
  -     142,548 Shared libraries -0.28% (of 51,768,960)
  -     167,936 Package size difference -0.57% (of 29,604,197)

For Android applications which make use of allot of resource, these changes can also impact startup times.
The follow are the start up improvements on the Android Application and Library projects both of which use AndroidX.

### All runs
| Before  | After   | Δ        | Notes                                |
| ------- | ------- | -------- | ------------------------------------ |
| 188.500 | 176.150 | -6.55% ✓ | defaults; 32-bit build               |
| 174.150 | 175.100 | +0.54% ✗ | defaults; profiled AOT; 32-bit build |
| 187.550 | 178.300 | -4.93% ✓ | defaults; full AOT; 32-bit build     |
| 173.250 | 174.050 | +0.46% ✗ | defaults; 64-bit build               |
| 186.400 | 176.450 | -5.34% ✓ | defaults; profiled AOT; 64-bit build |
| 181.350 | 174.400 | -3.83% ✓ | defaults; full AOT; 64-bit build     |

@dellis1972 dellis1972 added the do-not-merge PR should not be merged. label Feb 3, 2022
@dellis1972 dellis1972 changed the title [Xamarin.Android.Build.Tasks] Fix the RemoveResourceDesignerStep to work under .NET 6 [Xamarin.Android.Build.Tasks] Fix the RemoveResourceDesignerStep to work under .NET 6 [WIP] Feb 3, 2022
@dellis1972 dellis1972 removed the do-not-merge PR should not be merged. label Feb 8, 2022
@dellis1972 dellis1972 changed the title [Xamarin.Android.Build.Tasks] Fix the RemoveResourceDesignerStep to work under .NET 6 [WIP] [Xamarin.Android.Build.Tasks] Fix the RemoveResourceDesignerStep to work under .NET 6 Feb 8, 2022
@dellis1972
Copy link
Contributor Author

Need to fix up the ApkSize regression checks because of

Summary:
  +          29 Other entries 0.00% (of 923,350)
  -     193,742 Assemblies -4.27% (of 4,538,747)
  +           0 Dalvik executables 0.00% (of 3,483,796)
  -       3,952 Shared libraries -0.08% (of 4,702,944)
  -     196,608 Package size difference -2.29% (of 8,578,814)
stdErr: Error: apkdiff: File 'assemblies/Xamarin.Forms.Platform.dll' has changed by -45,963 bytes (-421.10 %). This exceeds the threshold of 5.00 %.
Error: apkdiff: File 'assemblies/Xamarin.Forms.Platform.Android.dll' has changed by -47,495 bytes (-14.07 %). This exceeds the threshold of 5.00 %.
Error: apkdiff: File 'assemblies/UnnamedProject.dll' has changed by -105,255 bytes (-878.30 %). This exceeds the threshold of 5.00 %.
Error: apkdiff: Size regression occured, 3 check(s) failed.

@dellis1972 dellis1972 changed the title [Xamarin.Android.Build.Tasks] Fix the RemoveResourceDesignerStep to work under .NET 6 [Xamarin.Android.Build.Tasks] Turn 'AndroidLinkResources' on by default for .NET 6 Release Applications Feb 9, 2022
@dellis1972
Copy link
Contributor Author

Hmm

Having code like this in the app causes a breakage a runtime with AndroidLinkResources turned on.

int iconDimen = Resource.Styleable.AlertDialog[Resource.Styleable.AlertDialog_buttonIconDimen];
android.runtime.JavaProxyThrowable: System.BadImageFormatException: Could not resolve field token 0x0400052b

This is because we are removing everything from the Resource.designer code, but we only replace the int fields.
So perhaps we should only remove the int ones.

@dellis1972 dellis1972 force-pushed the resourcelinker branch 4 times, most recently from 28c0696 to 1fe732a Compare February 15, 2022 16:54
… work under .NET 6

The current implementation of the `RemoveResourceDesignerStep` does not
work under .NET 6. This is mostly down to the fact that we didn't
`override` the require methods to make it work in that environment.

This PR does also rework the `RemoveResourceDesignerStep` to split some
of the functionality out into a new base class. This new base class will
be used in the future by the Resource Assembly linker step. Since much of
the code is identical.
@dellis1972 dellis1972 changed the title [Xamarin.Android.Build.Tasks] Turn 'AndroidLinkResources' on by default for .NET 6 Release Applications [Xamarin.Android.Build.Tasks] Enable 'AndroidLinkResources' for .NET 6 Release Applications Feb 15, 2022
Copy link
Member

@jonathanpeppers jonathanpeppers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add a test case for:

int iconDimen = Resource.Styleable.AlertDialog[Resource.Styleable.AlertDialog_buttonIconDimen];

Some test that check this works at runtime?

Copy link
Member

@jonathanpeppers jonathanpeppers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you have to opt into $(AndroidLinkResources), I think we could take this as-is.

@jonpryor
Copy link
Member

Context: https://github.com/xamarin/xamarin-android/pull/6427

The current implementation of the `RemoveResourceDesignerStep` linker
step does not work under .NET 6.  This is mostly down to the fact
that we didn't `override` the require methods to make it work in that
environment.

Reworks `RemoveResourceDesignerStep` to split some of the
functionality out into a new `LinkDesignerBase` base class.
`LinkDesignerBase` will be used in the future by the Resource Assembly
linker step xamarin/xamarin-android#6427.

`.apk` size difference in a Basic Android Application shows a
effectively no reduction in Package size.  This is a single App Head
project with no additional libraries or Nuget references:

	Size difference in bytes ([*1] apk1 only, [*2] apk2 only):
	  -         596 assemblies/assemblies.blob
	  -         760 lib/x86/libaot-DotNet6AndroidBasic.dll.so
	  -         764 lib/armeabi-v7a/libaot-DotNet6AndroidBasic.dll.so
	  -         864 lib/x86_64/libaot-DotNet6AndroidBasic.dll.so
	  -       5,032 lib/arm64-v8a/libaot-DotNet6AndroidBasic.dll.so
	Summary:
	  -         596 Other entries -0.03% (of 2,347,758)
	  +           0 Dalvik executables 0.00% (of 333,284)
	  -       7,420 Shared libraries -0.03% (of 23,525,172)
	  +           0 Package size difference 0.00% (of 11,745,501)

`.apk` size difference in a Basic Android app which references
AndroidX, shows a Package size reduction of ~164Kb.  This example
includes an App Head project as well as a single Android Library
project.  Both projects contain 2-3 `@(AndroidResource)` items and
both reference AndroidX.  `Resource.Designer.cs` file is 460kb in size.

	Size difference in bytes ([*1] apk1 only, [*2] apk2 only):
	  -      63,664 lib/x86/libaot-DotNet6AndroidTest.App.dll.so
	  -      63,952 lib/x86_64/libaot-DotNet6AndroidTest.App.dll.so
	  -      83,900 assemblies/assemblies.blob
	  -      84,408 lib/arm64-v8a/libaot-DotNet6AndroidTest.App.dll.so
	  -      92,340 lib/armeabi-v7a/libaot-DotNet6AndroidTest.App.dll.so
	Summary:
	  -      83,900 Other entries -2.83% (of 2,965,109)
	  +           0 Dalvik executables 0.00% (of 959,460)
	  -     304,364 Shared libraries -1.28% (of 23,781,188)
	  -     163,840 Package size difference -1.30% (of 12,620,512)

`.apk` size difference for a Basic Maui application shows a
Package size reduction of ~168Kb.  This is just a standard
`dotnet new maui` app built for the Android platform:

	Size difference in bytes ([*1] apk1 only, [*2] apk2 only):
	  +          24 lib/arm64-v8a/libaot-Microsoft.Maui.Graphics.dll.so
	  -          48 lib/arm64-v8a/libaot-Microsoft.Maui.Controls.Xaml.dll.so
	  -         396 lib/armeabi-v7a/libaot-Microsoft.Maui.dll.so
	  -         448 lib/arm64-v8a/libaot-Microsoft.Maui.dll.so
	  -         536 lib/x86/libaot-Microsoft.Maui.Controls.Compatibility.dll.so
	  -         592 lib/x86_64/libaot-Microsoft.Maui.Controls.Compatibility.dll.so
	  -         632 lib/armeabi-v7a/libaot-Microsoft.Maui.Controls.dll.so
	  -         632 lib/x86/libaot-Microsoft.Maui.Controls.dll.so
	  -         720 lib/x86_64/libaot-Microsoft.Maui.Controls.dll.so
	  -       4,492 lib/x86/libaot-Microsoft.Maui.dll.so
	  -       4,544 lib/x86_64/libaot-Microsoft.Maui.dll.so
	  -       4,568 lib/arm64-v8a/libaot-Microsoft.Maui.Controls.Compatibility.dll.so
	  -       4,628 lib/armeabi-v7a/libaot-Microsoft.Maui.Controls.Compatibility.dll.so
	  -       4,792 lib/arm64-v8a/libaot-Microsoft.Maui.Controls.dll.so
	  -      26,676 lib/x86/libaot-BasicMauiApp.dll.so
	  -      27,000 lib/x86_64/libaot-BasicMauiApp.dll.so
	  -      30,772 lib/armeabi-v7a/libaot-BasicMauiApp.dll.so
	  -      31,096 lib/arm64-v8a/libaot-BasicMauiApp.dll.so
	  -     124,129 assemblies/assemblies.blob
	Summary:
	  -     124,129 Other entries -1.18% (of 10,513,973)
	  +           0 Dalvik executables 0.00% (of 6,459,432)
	  -     142,548 Shared libraries -0.28% (of 51,768,960)
	  -     167,936 Package size difference -0.57% (of 29,604,197)

For Android applications which make use of lots of resources, these
changes can also impact startup times.  The follow are the start up
improvements on the Android Application and Library projects, both of
which use AndroidX.

| Before (ms) |  After (ms) |     Δ (%) | Notes                                |
| ----------: | ----------: | --------: | ------------------------------------ |
|     188.500 |     176.150 |  -6.55% ✓ | defaults; 32-bit build               |
|     174.150 |     175.100 |  +0.54% ✗ | defaults; profiled AOT; 32-bit build |
|     187.550 |     178.300 |  -4.93% ✓ | defaults; full AOT; 32-bit build     |
|     173.250 |     174.050 |  +0.46% ✗ | defaults; 64-bit build               |
|     186.400 |     176.450 |  -5.34% ✓ | defaults; profiled AOT; 64-bit build |
|     181.350 |     174.400 |  -3.83% ✓ | defaults; full AOT; 64-bit build     |

~~ Known Issues ~~

`RemoveResourceDesignerStep` doesn't work properly with array
resources; consider:

	int iconDimen = Resource.Styleable.AlertDialog[Resource.Styleable.AlertDialog_buttonIconDimen];

The `RemoveResourceDesignerStep` will *remove* the
`Resource.Styleable.AlertDialog` field, but the field is still
accessed (?!), resulting in a `BadImageFormatException` at runtime:

	android.runtime.JavaProxyThrowable: System.BadImageFormatException: Could not resolve field token 0x0400052b

@jonpryor jonpryor merged commit c80dfff into dotnet:main Feb 16, 2022
@dellis1972 dellis1972 deleted the resourcelinker branch November 30, 2022 16:04
@github-actions github-actions bot locked and limited conversation to collaborators Jan 24, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants