xamarin / AndroidSupportComponents

Xamarin bindings for Android Support libraries - For AndroidX see https://github.com/xamarin/AndroidX
MIT License
146 stars 56 forks source link

[assembly:LinkerSafe] inconsistency. Didn't find class "android.support.v7.widget.FitWindowsFrameLayout". #219

Closed yaliashkevich closed 4 years ago

yaliashkevich commented 5 years ago

Xamarin.Android Version:

9.1.7.0

Operating System & Version:

Win 10 / macOS 10.14.6

Support Libraries Version):

28.0.0.3

Describe your Issue:

After updating target sdk version from 26 to 28 (to meet google play api level requirements) my app began crashing at startup with following error:

10-15 21:43:19.784 22915 22915 E AndroidRuntime: Caused by: android.view.InflateException: Binary XML file line #20: Error inflating class android.support.v7.widget.FitWindowsFrameLayout 10-15 21:43:19.784 22915 22915 E AndroidRuntime: Caused by: java.lang.ClassNotFoundException: Didn't find class "android.support.v7.widget.FitWindowsFrameLayout"

After digging a lot I found out that that generated obj/90/proguard_project_references.cfg files has missed a lot of keep rules in comparison to obj/80/proguard_project_references.cfg, for instance

-keep class android.support.v7.widget.FitWindowsFrameLayout

Looking into the reason why this happening I finally found out that monoandroid90 assembly from nuget package has LinkerSafe attribute:

LinkerSafe

So I have few questions here:

  1. Is it intended to have this linker-inconsistent behavior for same nuget package but different targets frameworks?

  2. Why this LinkerSafe attribute applied at all, if in fact it is not safe in a very basic scenario? I mean I have "SDK only" linker option and I do expect doing nothing extra (configuring proguard rules) for non sdk libraries.

I was not able to find xamarin.android documentation for LinkerSafe attribute, but for iOS counterpart it says following:

Use this attribute in your assembly if it is safe to perform linking on it, regardless of the user default setting to "Link only Framework Assemblies.

The use case for this attribute are third-party libraries that are safe to be linked because they have either safe to be linked because they do not depend on members or methods to be compiled in to work, or if they do, they used the PreserveAttribute to preserve those classes.

https://docs.microsoft.com/en-us/dotnet/api/foundation.linkersafeattribute?view=xamarin-ios-sdk-12#remarks

... and obviously support library packages are not safe.

yaliashkevich commented 5 years ago

Just to help or speed up triage:

LinkerSafe change introduced here https://github.com/xamarin/AndroidSupportComponents/pull/77 should be reverted. There is no way you can mark assembly which types instantiated by reflection during inflate from xml with LinkerSafe attribute, even if you have it tested :) on empty app from VS template. That is not safe by definition, until workaround from here https://github.com/xamarin/xamarin-android/issues/3636 is part of default build process.

If I as a developer need to optimize app size I can use "Link All" or/and use custom linker configuration. If I understand correctly right now there is no way to opt out from linking support libraries.

Update of nuget packages without LinkerSafe attribute is really appreciated .

yaliashkevich commented 4 years ago

Close as https://github.com/xamarin/xamarin-android/issues/3636 released in Xamarin.Android 10.3.1.0