如何在适用于Android的Xamarin.Forms应用程序中使用D8,R8?

时间:2019-01-27 18:21:58

标签: xamarin xamarin.forms xamarin.android

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

建议按以下方式使用,并告知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.

此外,这些设置如何将效果捆绑到本机程序集,AotAssemblies,LLVM等中?我们可以和他们一起使用吗?我的配置如下。但不幸的是,它不起作用。如果我删除D8和R8,它的工作原理。我尝试仅使用Proguard + D8,但也无法正常工作。

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</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.Droid\myApp.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.Droid\myApp.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>

2 个答案:

答案 0 :(得分:1)

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

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

我花了整整一天的时间使用现有的proguard运行我的现有应用程序,因为它被保证可以与我现有的应用程序一起使用。这是我遇到的一些问题;

  1. 某些nuget软件包在r8上失败,而在proguard上可以正常工作。例如,我对OneSignal库有问题。这是github上的issue。我相信其他一些图书馆也会有问题。
  2. Proguard optimizations被r8识别。这太疯狂了,因为您没有得到确切的错误消息,而只有this消息。尽管我启用了诊断构建,但您甚至不知道它的含义。我通过删除proguard中的每一行来弄清楚,每次都必须在发行版中进行重建。您可能会想象这是多么痛苦,因为每个构建可能要花费5-10分钟的时间,并且您必须重复几次。 最终,我发现我在proguard error : java.lang.StringIndexOutOfBoundsException: String index out of range : 4735中有这行,而r8不喜欢它。
  3. 我最终可以在手机上进行重建和部署而没有任何错误,并且应用程序在启动时崩溃了。我没有修复它,因为我想在尝试修复某些东西之前先了解一下自己的收获。

结果:

据说,apk和dex文件的大小有所减少,但实际情况却很少。 我使用以下启用的设置;  -optimizations !field/removal/writeonly,!field/marking/private,!class/merging/*,!code/allocation/variable用于每两次测试

  
      
  1. 具有multidex + proguard = apk大小26,4mb的应用程序dex大小3,4mb的应用程序
  2.   
  3. 应用程式D8 + R8 +无multidex +无proguard的= APK大小26,2mb DEX尺寸2,7mb
  4.   

在Xamarin的早期阶段看到d8和r8支持绝对令人兴奋和乐观。我们对此表示赞赏,但是对于那些想要像我一样快尝试的人,这还不值得。将来也许我们可以重新考虑这些选项,但是对于现在的多dex,proguard似乎是更好的选择。

答案 1 :(得分:0)

除了我的构建因关于org.apache.http的错误而失败的问题(已由https://github.com/xamarin/xamarin-android/issues/2670修复)之外,我发现此配置对我有用...

 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</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卡住了。