如何在Xamarin.Forms Android应用程序中使用D8、R8



我刚刚下载了Vs 2019 pre,它为xamarin android提供了更多配置,如所述

它建议如下使用,并告诉proguard不能与r8一起使用,因为它是proguard的替代品。

<Project>
<PropertyGroup>
<AndroidEnableMultiDex>True</AndroidEnableMultiDex>
<AndroidDexTool>d8</AndroidDexTool>
<AndroidLinkTool>r8</AndroidLinkTool>
</PropertyGroup>
</Project>

但我真的不明白r8应该怎么工作?因为使用proguard,我做了很多配置,比如定义保留哪个库、类和函数。所以我们不需要这些吗?只需设置r8就可以了?我已经按照建议尝试了,但我错了8>R8 : error : Compilation can't be completed because some library classes are missing.

除此之外,这些设置是如何将绑定绑定到本机程序集、AotAssembly、LLVM等中的?我们可以和他们一起使用吗。我的配置如下。但不幸的是,它不起作用。如果我去掉D8和R8,它就起作用了。我试着只使用Proguard+D8,但也不起作用。

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Optimize>true</Optimize>
<OutputPath>binRelease</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AndroidUseSharedRuntime>False</AndroidUseSharedRuntime>
<DebugType>portable</DebugType>
<AndroidLinkMode>Full</AndroidLinkMode>
<EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk>
<AndroidCreatePackagePerAbi>true</AndroidCreatePackagePerAbi>
<JavaMaximumHeapSize>1G</JavaMaximumHeapSize>
<AotAssemblies>true</AotAssemblies>
<EnableLLVM>true</EnableLLVM>
<AndroidAotAdditionalArguments>no-write-symbols,nodebug</AndroidAotAdditionalArguments>
<DebugSymbols>false</DebugSymbols>
<BundleAssemblies>true</BundleAssemblies>
<AndroidEnableMultiDex>True</AndroidEnableMultiDex>
<EnableProguard>false</EnableProguard>
<Debugger>Xamarin</Debugger>
<AndroidSupportedAbis>armeabi-v7a;x86;x86_64</AndroidSupportedAbis>
<AndroidLinkSkip> </AndroidLinkSkip>
<AndroidEnableMultipleDex>true</AndroidEnableMultipleDex>
<AndroidExplicitCrunch>true</AndroidExplicitCrunch>
<AndroidDexTool>d8</AndroidDexTool>
<AndroidLinkTool>r8</AndroidLinkTool>
</PropertyGroup>

更新:

我移除r8并启用proguard。因为在阅读后,一般(不仅仅是xamarin)r8不如proguard成熟。所以我只让d8高于configuarion和EnableProguard=true。但我收到了关于r8 的警告和错误

8>"myApp.DroidmyApp.Droid.csproj" (Rebuild;BuiltProjectOutputGroup;BuiltProjectOutputGroupDependencies;DebugSymbolsProjectOutputGroup;DebugSymbolsProjectOutputGroupDependencies;DocumentationProjectOutputGroup;DocumentationProjectOutputGroupDependencies;SatelliteDllsProjectOutputGroup;SatelliteDllsProjectOutputGroupDependencies;SGenFilesOutputGroup;SGenFilesOutputGroupDependencies target) (1) ->
8>(_CompileToDalvikWithD8 target) -> 
8>  R8 : warning : Missing class: com.amazon.device.messaging.ADMMessageReceiver
8>  R8 : warning : Missing class: com.google.android.gms.location.LocationListener
8>  R8 : warning : Missing class: com.amazon.device.messaging.ADMMessageHandlerBase
8>  R8 : warning : Missing class: com.amazon.device.iap.PurchasingListener
8>  R8 : warning : Missing class: org.apache.http.client.methods.HttpEntityEnclosingRequestBase
8>
8>
8>"myApp.DroidmyApp.Droid.csproj" (Rebuild;BuiltProjectOutputGroup;BuiltProjectOutputGroupDependencies;DebugSymbolsProjectOutputGroup;DebugSymbolsProjectOutputGroupDependencies;DocumentationProjectOutputGroup;DocumentationProjectOutputGroupDependencies;SatelliteDllsProjectOutputGroup;SatelliteDllsProjectOutputGroupDependencies;SGenFilesOutputGroup;SGenFilesOutputGroupDependencies target) (1) ->
8>(_CompileToDalvikWithD8 target) -> 
8>  R8 : error : Compilation can't be completed because some library classes are missing.
8>
8>    45 Warning(s)
8>    1 Error(s)
8>

我想在这里为那些对将D8和R8用于xamarin表单应用程序感到兴奋的人提供更新。

最后一件事是,它还没有准备好,还没有明显的优势。不要浪费你的时间

我花了几乎一整天的时间用现有的proguard运行我现有的应用程序,因为它被承诺应该与我现有的程序一起工作。以下是我遇到的一些问题;

  1. 一些nuget包在r8中失败,而在proguard中运行良好。例如,我对OneSignal库有问题。这是github上的问题。我相信其他一些图书馆也会有问题
  2. r8无法识别Proguard优化。这太疯狂了,因为您并没有得到确切的错误消息,只得到了error : java.lang.StringIndexOutOfBoundsException: String index out of range : 4735的消息。尽管我启用了诊断构建,但你甚至不知道它是关于什么的。我通过删除proguard中的每一行来解决这个问题,每次都必须在发布时重新构建。你可以想象这是多么痛苦,因为每次构建可能需要5-10分钟,而且你必须重复几次。最后我发现我的proguard-optimizations !field/removal/writeonly,!field/marking/private,!class/merging/*,!code/allocation/variable中有这条线,r8不喜欢它
  3. 我能够在手机上重建和部署,最后没有任何错误,应用程序在启动时崩溃。我没有修复它,因为我想在尝试修复某个东西之前看到自己的收获

结果:

据说apk和dex文件的大小减少了,但实际情况却很小。我启用了以下设置;Aot+lvvm+bundle into native assemblies+ CreatePackagePerAbi+ Full linking用于每2次测试

  1. 具有multidex+proguard=apk大小26,4mb dex大小3,4mb的应用程序
  2. 带d8+r8+无多功能+无proguard的应用程序=apk大小26,2mb dex大小2.7mb

在Xamarin的早期阶段看到d8和r8的支持无疑是令人兴奋和积极的。我们很感激,但对于像我这样想这么快尝试的人来说,这还不值得。未来也许我们可以重新考虑这些选择,但就目前而言,multi-dex、proguard似乎是更好的选择。

除了我的构建因org.apache.http的错误而失败的问题之外(https://github.com/xamarin/xamarin-android/issues/2670)我发现这个配置对我有用…

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Optimize>true</Optimize>
<OutputPath>binRelease</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AndroidLinkMode>SdkOnly</AndroidLinkMode>
<AndroidSupportedAbis>armeabi-v7a;x86;arm64-v8a;x86_64</AndroidSupportedAbis>
<AndroidCreatePackagePerAbi>true</AndroidCreatePackagePerAbi>
<AndroidHttpClientHandlerType>Xamarin.Android.Net.AndroidClientHandler</AndroidHttpClientHandlerType>
<!-- Alternative to using Proguard -->
<AndroidDexTool>d8</AndroidDexTool>
<AndroidLinkTool>r8</AndroidLinkTool>
<!-- (A) Recommended AOT settings based on https://forums.xamarin.com/discussion/104165/when-will-be-aot-available-again -->
<EmbedAssembliesIntoApk>True</EmbedAssembliesIntoApk> <!-- See (A) -->
<BundleAssemblies>True</BundleAssemblies> <!-- See (A) -->
<AotAssemblies>True</AotAssemblies> <!-- See (A) -->
<EnableLLVM>True</EnableLLVM> <!-- See (A) -->
<!-- TODO Startup Tracing -->
</PropertyGroup>

这项部署成功了,速度更快,即使添加了AOT,APK的大小现在也比我最初不使用ProGuard/AOT的构建略小。

请注意,Xamarin Studio(社区)不允许您为Android设置AOT/LLVM选项,因此您必须直接编辑项目。

此外,打开构建/归档窗口也是值得的,因为这需要很长时间(尤其是如果你要为每个架构吐出一个单独的ABI),有一段时间我认为Xamarin Studio陷入了困境。

最新更新