.NET MAUI Android アプリのリンク
アプリをビルドするときに、.NET Multi-platform App UI (.NET MAUI) で、ILLink というリンカーを使用して、アプリの全体的なサイズを縮小できます。 ILLink は、コンパイラによって生成された中間コードを分析することによってサイズを小さくします。 使用されていないメソッド、プロパティ、フィールド、イベント、構造体、クラスを削除して、アプリの実行に必要なコードとアセンブリの依存関係のみを含むアプリを生成します。
リンカーの動作
リンカーを使用すると、.NET MAUI Android アプリをトリミングできます。 トリミングが有効になっている場合、リンカーは、ユーザーのアセンブリをそのままにし、アプリで使用しない型やメンバーを削除することで SDK アセンブリのサイズを縮小します。
リンカーの動作は、アプリのビルド構成ごとに構成できます。 既定では、トリミングはデバッグ ビルドでは無効になり、リリース ビルドでは有効になります。
警告
アプリのデバッグ構成に対してリンカーを有効にすると、オブジェクトの状態を検査できるプロパティ アクセサーが削除される可能性があるため、デバッグ エクスペリエンスが妨げられる可能性があります。
トリミングが有効になっていることを確認するには、次の手順を行います。
Visual Studio では、ソリューション エクスプローラーで、.NET MAUI アプリ プロジェクトを右クリックし、[プロパティ] を選択します。 次に、[Android] > [オプション] タブに移動し、リリース ビルド構成に対してトリミングが有効になっていることを確認します。
コードを保持する
トリマを使用すると、動的に呼び出した可能性のあるコードが、間接的に削除されることがあります。 属性を使用してメンバーに注釈を付けることで、メンバーを保持するようにトリマーに DynamicDependency
指示できます。 この属性は、メンバーの型とサブセット、または特定のメンバーへの依存関係を表すために使用できます。
重要
アプリで使用されると静的に判断できない BCL 内のすべてのメンバーが削除される可能性があります。
DynamicDependency
属性は、コンストラクター、フィールド、メソッドに適用できます。
[DynamicDependency("Helper", "MyType", "MyAssembly")]
static void RunHelper()
{
var helper = Assembly.Load("MyAssembly").GetType("MyType").GetMethod("Helper");
helper.Invoke(null, null);
}
この例では、DynamicDependency
は Helper
メソッドが保持されていることを確認します。 属性がない場合、トリミングは他の場所からMyAssembly
参照されていない場合は完全に削除Helper
MyAssembly
されます。
この属性では、string
または DynamicallyAccessedMembers
属性を介して保持するメンバーを指定します。 型とアセンブリは、属性コンテキスト内で暗黙的に指定されるか、または属性内で明示的に指定されます (Type
によって、または型とアセンブリ名の場合は string
によって)。
型とメンバーの文字列では、C# ドキュメントのコメント ID 文字列の形式 のバリエーションを、メンバー プレフィックスなしで使用します。 メンバー文字列には、宣言する型の名前を含めることはできません。指定した名前のすべてのメンバーを保持するにはパラメーターを省略してかまいません。 次の例は、有効な用途を示しています。
[DynamicDependency("Method()")]
[DynamicDependency("Method(System,Boolean,System.String)")]
[DynamicDependency("MethodOnDifferentType()", typeof(ContainingType))]
[DynamicDependency("MemberName")]
[DynamicDependency("MemberOnUnreferencedAssembly", "ContainingType", "UnreferencedAssembly")]
[DynamicDependency("MemberName", "Namespace.ContainingType.NestedType", "Assembly")]
// generics
[DynamicDependency("GenericMethodName``1")]
[DynamicDependency("GenericMethod``2(``0,``1)")]
[DynamicDependency("MethodWithGenericParameterTypes(System.Collections.Generic.List{System.String})")]
[DynamicDependency("MethodOnGenericType(`0)", "GenericType`1", "UnreferencedAssembly")]
[DynamicDependency("MethodOnGenericType(`0)", typeof(GenericType<>))]
アセンブリを保持する
他のアセンブリをトリミングできるようにしながら、トリミング プロセスから除外するアセンブリを指定できます。 この方法は、属性を簡単に DynamicDependency
使用できない場合や、トリミングされるコードを制御できない場合に役立ちます。
すべてのアセンブリをトリミングするときに、プロジェクト ファイルで MSBuild 項目を設定 TrimmerRootAssembly
することで、アセンブリをスキップするようにトリマーに指示できます。
<ItemGroup>
<TrimmerRootAssembly Include="MyAssembly" />
</ItemGroup>
Note
TrimmerRootAssembly
MSBuild プロパティを設定するときに、.dll
拡張機能は必要ありません。
トリマーがアセンブリをスキップすると、ルート化されたと見な されます。つまり、そのアセンブリとその静的に認識されたすべての依存関係が保持されます。 <ItemGroup>
に TrimmerRootAssembly
MSBuild プロパティを追加することで、追加のアセンブリをスキップできます。
アセンブリ、型、メンバーを保持する
保持する必要があるアセンブリ、型、およびメンバーを指定する XML 記述ファイルをトリマーに渡すことができます。
すべてのアセンブリをトリミングするときにメンバーをトリミング プロセスから除外するには、プロジェクト ファイル内の TrimmerRootDescriptor
MSBuild 項目を、除外するメンバーを定義する XML ファイルに設定します。
<ItemGroup>
<TrimmerRootDescriptor Include="MyRoots.xml" />
</ItemGroup>
その後、XML ファイルはトリマ 記述子形式 を使用して、除外するメンバーを定義します。
<linker>
<assembly fullname="MyAssembly">
<type fullname="MyAssembly.MyClass">
<method name="DynamicallyAccessedMethod" />
</type>
</assembly>
</linker>
この例では、XML ファイルは、トリミングから除外される、アプリによって動的にアクセスされるメソッドを指定します。
アセンブリ、型、またはメンバーが XML にリストされている場合、既定のアクションは保持です。つまり、トリマーが使用されていると見なすかどうかにかかわらず、出力に保持されます。
Note
保持タグはあいまいに包括的です。 次のレベルの詳細を指定しない場合は、すべての子が含まれます。 アセンブリが型なしで一覧表示されている場合は、アセンブリのすべての型とメンバーが保持されます。
アセンブリをトリム セーフとしてマークする
プロジェクトにライブラリがある場合、または再利用可能なライブラリの開発者で、トリマでアセンブリをトリミング可能として扱いたい場合は、アセンブリのプロジェクト ファイルに MSBuild プロパティを追加 IsTrimmable
することで、アセンブリをトリム セーフとしてマークできます。
<PropertyGroup>
<IsTrimmable>true</IsTrimmable>
</PropertyGroup>
これにより、アセンブリが「トリミング可能」としてマークされ、そのプロジェクトに対するトリミングの警告が有効になります。 「トリミング可能」とは、ライブラリがトリミングと互換性があると見なされ、ライブラリのビルド時にトリミングの警告が発生しないはずであることを意味します。 トリミングされたアプリで使用されたとき、最終的な出力において、アセンブリではその未使用のメンバーが削除されます。
プロジェクト ファイルで IsTrimmable
MSBuild プロパティを true
に設定すると、アセンブリに AssemblyMetadata
属性が挿入されます。
[assembly: AssemblyMetadata("IsTrimmable", "True")]
または、アセンブリのプロジェクト ファイルに IsTrimmable
MSBuild プロパティを追加せずに、アセンブリに AssemblyMetadata
属性を追加することもできます。
Note
アセンブリに対して IsTrimmable
MSBuild プロパティが設定されている場合は、AssemblyMetadata("IsTrimmable", "True")
属性がオーバーライドされます。 これにより、属性がない場合でもアセンブリのトリミングを選択したり、属性を持つアセンブリのトリミングを無効にしたりすることができます。
分析の警告を抑制する
トリマーが有効になっていると、静的に到達できない IL が削除されます。 リフレクションまたは動的な依存関係を作成するその他のパターンを使用するアプリは、結果として壊れることがあります。 このようなパターンに関する警告を表示するには、アセンブリをトリム セーフとしてマークする場合、ライブラリ作成者は MSBuild プロパティを SuppressTrimAnalysisWarnings
次のように設定する false
必要があります。
<PropertyGroup>
<SuppressTrimAnalysisWarnings>false</SuppressTrimAnalysisWarnings>
</PropertyGroup>
トリミング分析の警告を抑制しない場合、独自のコード、ライブラリ コード、SDK コードを含む、アプリ全体に関する警告が含まれます。
詳細な警告の表示
トリミング分析では、アセンブリの内部構造とトリミングに互換性がないことを示す PackageReference
からの警告が、アセンブリごとに最大で 1 つ生成されます。 ライブラリの作成者として、アセンブリをトリム セーフとしてマークする場合は、MSBuild プロパティを次のように設定して、すべてのアセンブリに対して個別の TrimmerSingleWarn
警告を有効にする false
必要があります。
<PropertyGroup>
<TrimmerSingleWarn>false</TrimmerSingleWarn>
</PropertyGroup>
この設定により、アセンブリごとに 1 つの警告に折りたたむのではなく、すべての詳細な警告を表示します。
.NET MAUI