Skip to content

Commit 2e64c99

Browse files
[android] use a custom Resource.designer.cs
Context: https://github.com/jonathanpeppers/CustomResourceDesigner Context: dotnet/android#6310 We found a systemic problem with Xamarin.Android class libraries: * Include AndroidX & Google Material * Include at least one `@(AndroidResource)` and use the ID from C# * `Resource.designer.cs` has 2,700+ fields. That's a lot! This problem compounds itself as you include more class libraries that depend on each other. The main app will end up repeatedly setting these fields at startup for each library that contains fields in `Resource.designer.cs`... Reviewing the .NET MAUI fields, I found: src\Core\src\obj\Debug\net6.0-android\Resource.designer.cs 5310 src\Controls\src\Core\obj\Debug\net6.0-android\Resource.designer.cs 5167 fields src\Controls\src\Xaml\obj\Release\net6.0-android\Resource.designer.cs 5167 fields src\Compatibility\Core\src\obj\Debug\net6.0-android\Resource.designer.cs 5333 fields src\Essentials\src\obj\Debug\net6.0-android\Resource.designer.cs 204 fields In fact, I found 21,497 fields were set at startup for a `dotnet new maui` app in `Resource.designer.cs`! In many projects you can simply set `$(AndroidGenerateResourceDesigner)` to `false`, but the issue is .NET MAUI actually uses some of the C# `Resource.designer.cs` values at runtime. So to solve the problem here, I came up with a new pattern: https://github.com/jonathanpeppers/CustomResourceDesigner We can copy the contents of `Resource.designer.cs` and manually delete all the fields we don't need. This allows `$(AndroidGenerateResourceDesigner)` to be turned off. We are working on a long-term solution for this issue in Xamarin.Android, but we can do this workaround in .NET MAUI now. ~~ Results ~~ Building a `dotnet new maui` then `dotnet build -c Release` and running on a Pixel 5. Before: * 21,497 fields set at startup in UpdateIdValues() * Activity Displayed: 1s454ms * .apk size: 17300275 bytes After: * 65 fields set at startup in UpdateIdValues() * Activity Displayed: 1s079ms * .apk size: 16677683 bytes > apkdiff -f before.apk after.apk Size difference in bytes ([*1] apk1 only, [*2] apk2 only): - 233 assemblies/Microsoft.Maui.Controls.Compatibility.Android.FormsViewGroup.dll - 5,264 assemblies/Microsoft.Maui.Essentials.dll - 103,010 assemblies/Microsoft.Maui.dll - 103,260 assemblies/Microsoft.Maui.Controls.Compatibility.dll - 103,811 assemblies/Microsoft.Maui.Controls.Xaml.dll - 106,127 assemblies/Microsoft.Maui.Controls.dll - 201,031 assemblies/foo.dll Summary: + 0 Other entries 0.00% (of 2,139,558) - 622,736 Assemblies -6.93% (of 8,987,664) + 0 Dalvik executables 0.00% (of 6,440,988) + 0 Shared libraries 0.00% (of 9,860,264) - 1,340,928 Uncompressed assemblies -6.55% (of 20,465,016) - 622,592 Package size difference -3.60% (of 17,300,275)
1 parent b4f0e6f commit 2e64c99

File tree

5 files changed

+433
-0
lines changed

5 files changed

+433
-0
lines changed

DEVELOPMENT.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,32 @@ To build and run WinUI 3 support, please install the additional components menti
7171
dotnet tool restore
7272
dotnet cake --target=VS-WINUI
7373
```
74+
75+
### Android
76+
77+
To workaround a performance issue, all `Resource.designer.cs`
78+
generation is disabled for class libraries in this repo.
79+
80+
If you need to add a new `@(AndroidResource)` value to be used from C#
81+
code in .NET MAUI:
82+
83+
1. Comment out the `<PropertyGroup>` in `Directory.Build.targets` that
84+
sets `$(AndroidGenerateResourceDesigner)` and
85+
`$(AndroidUseIntermediateDesignerFile)` to `false`.
86+
87+
2. Build .NET MAUI as you normally would. You will get compiler errors
88+
about duplicate fields, but `obj\Debug\net6.0-android\Resource.designer.cs`
89+
should now be generated.
90+
91+
3. Open `obj\Debug\net6.0-android\Resource.designer.cs`, and find the
92+
field you need such as:
93+
94+
```csharp
95+
// aapt resource value: 0x7F010000
96+
public static int foo = 2130771968;
97+
```
98+
99+
4. Copy this field to the `Resource.designer.cs` checked into source
100+
control, such as: `src\Controls\src\Core\Platform\Android\Resource.designer.cs`
101+
102+
5. Restore the commented code in `Directory.Build.targets`.

Directory.Build.targets

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66
<Import Project="eng\AndroidX.targets" />
77
<Import Project="eng\Microsoft.Extensions.targets" />
88

9+
<PropertyGroup Condition="'$(TargetPlatformIdentifier)' == 'Android' and '$(AndroidApplication)' != 'true'">
10+
<AndroidGenerateResourceDesigner>false</AndroidGenerateResourceDesigner>
11+
<AndroidUseIntermediateDesignerFile>false</AndroidUseIntermediateDesignerFile>
12+
</PropertyGroup>
13+
914
<!-- HACK: Prevent the Platform checks -->
1015
<Target Name="BinPlaceBootstrapDll" />
1116

src/Compatibility/Core/src/Android/Resource.designer.cs

Lines changed: 143 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Controls/src/Core/Platform/Android/Resource.designer.cs

Lines changed: 140 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)