.NET MAUI Android 앱 연결

앱을 빌드할 때 .NET 다중 플랫폼 앱 UI(.NET MAUI)는 호출 ILLink 된 링커를 사용하여 앱의 전체 크기를 줄일 수 있습니다. ILLink 는 컴파일러에서 생성된 중간 코드를 분석하여 크기를 줄입니다. 사용되지 않는 메서드, 속성, 필드, 이벤트, 구조체 및 클래스를 제거하여 앱을 실행하는 데 필요한 코드 및 어셈블리 종속성만 포함하는 앱을 생성합니다.

링커 동작

링커를 사용하면 .NET MAUI Android 앱을 트리밍할 수 있습니다. 트리밍을 사용하도록 설정하면 링커는 어셈블리를 그대로 두고 앱에서 사용하지 않는 형식과 멤버를 제거하여 SDK 어셈블리의 크기를 줄입니다.

링커 동작은 앱의 각 빌드 구성에 대해 구성할 수 있습니다. 기본적으로 트리밍은 디버그 빌드에 대해 사용하지 않도록 설정되고 릴리스 빌드에 대해 사용하도록 설정됩니다.

Warning

앱의 디버그 구성에 링커를 사용하도록 설정하면 개체의 상태를 검사할 수 있는 속성 접근자가 제거될 수 있으므로 디버깅 환경이 저하될 수 있습니다.

  1. 솔루션 탐색기 .NET MAUI 앱 프로젝트를 마우스 오른쪽 단추로 클릭하고 속성을 선택합니다. 그런 다음, Android 옵션 탭으로 이동하여 릴리스 빌드 구성에 트리밍이 사용하도록 설정되어 있는지 확인합니다>.

    Screenshot of the linker behavior for Android in Visual Studio.

코드 유지

링커를 사용하면 간접적으로도 동적으로 호출했을 수 있는 코드가 제거되는 경우가 있습니다. 특성에 주석을 추가하여 멤버를 유지하도록 링커에 DynamicDependency 지시할 수 있습니다. 이 특성은 멤버의 형식 및 하위 집합 또는 특정 멤버에 대한 종속성을 표현하는 데 사용할 수 있습니다.

Important

앱에서 사용하도록 정적으로 확인할 수 없는 BCL의 모든 멤버는 제거될 수 있습니다.

DynamicDependency 생성자, 필드 및 메서드에 특성을 적용할 수 있습니다.

[DynamicDependency("Helper", "MyType", "MyAssembly")]
static void RunHelper()
{
    var helper = Assembly.Load("MyAssembly").GetType("MyType").GetMethod("Helper");
    helper.Invoke(null, null);
}

이 예제에서는 DynamicDependency 메서드가 유지되는지 확인합니다 Helper . 특성이 없으면 연결이 다른 곳에서 참조되지 않으면 완전히 제거되거나 제거 HelperMyAssemblyMyAssembly 됩니다.

특성은 특성을 통해 또는 특성을 통해 유지할 멤버를 stringDynamicallyAccessedMembers 지정합니다. 형식과 어셈블리는 특성 컨텍스트에서 암시적이거나 특성에서 명시적으로 지정됩니다(형식 및 어셈블리 이름에 대해 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> 어셈블리를 건너뛰도록 지시할 수 있습니다.

<ItemGroup>
  <TrimmerRootAssembly Include="MyAssembly" />
</ItemGroup>

참고 항목

.dll MSBuild 속성을 설정할 때 확장이 TrimmerRootAssembly 필요하지 않습니다.

링커가 어셈블리를 건너뛰면 루트간주됩니다. 즉, 해당 어셈블리와 정적으로 이해된 모든 종속성이 유지됩니다. MSBuild 속성을 더 추가하여 TrimmerRootAssembly 추가 어셈블리를 <ItemGroup>건너뛸 수 있습니다.

어셈블리, 형식 및 멤버 유지

보존해야 하는 어셈블리, 형식 및 멤버를 지정하는 XML 설명 파일을 링커에 전달할 수 있습니다.

모든 어셈블리를 연결할 때 연결 프로세스에서 멤버를 제외하려면 프로젝트 파일의 TrimmerRootDescriptor 태그에 있는 <ItemGroup> 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에 나열되면 기본 동작은 유지입니다. 즉, 링커가 사용한다고 생각하든 그렇지 않은지 여부에 관계없이 출력에 유지됩니다.

참고 항목

보존 태그는 모호하게 포괄합니다. 다음 수준의 세부 정보를 제공하지 않으면 모든 자식이 포함됩니다. 어셈블리가 형식 없이 나열되면 어셈블리의 모든 형식과 멤버가 유지됩니다.

어셈블리를 링커 안전으로 표시

프로젝트에 라이브러리가 있거나 재사용 가능한 라이브러리의 개발자이고 링커가 어셈블리를 연결 가능한 것으로 처리하려는 경우 MSBuild 속성을 어셈블리의 프로젝트 파일에 추가하여 IsTrimmable 어셈블리를 링커로 안전하게 표시할 수 있습니다.

<PropertyGroup>
    <IsTrimmable>true</IsTrimmable>
</PropertyGroup>

이렇게 하면 어셈블리가 "트리밍 가능"으로 표시되고 해당 프로젝트에 대한 트리밍 경고가 활성화됩니다. "트리밍 가능"이면 어셈블리가 트리밍과 호환되는 것으로 간주되며 어셈블리가 빌드될 때 트리밍 경고가 없어야 합니다. 트리밍된 앱에서 사용되는 경우 어셈블리의 사용되지 않은 멤버는 최종 출력에서 제거됩니다.

IsTrimmable MSBuild 속성을 true 프로젝트 파일로 설정하면 어셈블리에 특성이 AssemblyMetadata 삽입됩니다.

[assembly: AssemblyMetadata("IsTrimmable", "True")]

또는 MSBuild 속성을 어셈블리의 AssemblyMetadata 프로젝트 파일에 추가하지 않고 어셈블리에 특성을 추가할 IsTrimmable 수 있습니다.

참고 항목

어셈블리에 IsTrimmable 대해 MSBuild 속성이 설정된 경우 특성을 재정의 AssemblyMetadata("IsTrimmable", "True") 합니다. 이렇게 하면 특성이 없는 경우에도 어셈블리를 트리밍으로 선택하거나 특성이 있는 어셈블리의 트리밍을 사용하지 않도록 설정할 수 있습니다.

분석 경고 표시 안 함

링커를 사용하도록 설정하면 정적으로 연결할 수 없는 IL이 제거됩니다. 리플렉션 또는 동적 종속성을 만드는 다른 패턴을 사용하는 앱은 결과적으로 손상될 수 있습니다. 이러한 패턴에 대해 경고하려면 어셈블리를 링커 안전으로 표시할 때 라이브러리 작성자는 MSBuild 속성을 다음으로 false설정 SuppressTrimAnalysisWarnings 해야 합니다.

<PropertyGroup>
  <SuppressTrimAnalysisWarnings>false</SuppressTrimAnalysisWarnings>
</PropertyGroup>

트리밍 분석 경고를 표시하지 않으면 사용자 고유의 코드, 라이브러리 코드 및 SDK 코드를 포함하여 전체 앱에 대한 경고가 포함됩니다.

자세한 경고 표시

트리밍 분석은 어셈블리의 내부가 트리밍과 호환되지 않음을 나타내는 각 어셈블리에 PackageReference대해 최대 하나의 경고를 생성합니다. 라이브러리 작성자는 어셈블리를 링커 안전으로 표시할 때 MSBuild 속성을 false다음으로 설정 TrimmerSingleWarn 하여 모든 어셈블리에 대해 개별 경고를 사용하도록 설정해야 합니다.

<PropertyGroup>
  <TrimmerSingleWarn>false</TrimmerSingleWarn>
</PropertyGroup>

이 설정은 어셈블리당 단일 경고로 축소하는 대신 모든 자세한 경고를 표시합니다.

참고 항목