다음을 통해 공유


Xamarin.Android 바인딩 프로젝트 마이그레이션

.NET에서는 Android 바인딩 프로젝트에 별도의 프로젝트 형식이라는 개념이 없습니다. Xamarin.Android 바인딩 프로젝트에서 작동하는 MSBuild 항목 그룹 또는 빌드 작업은 Android용 .NET 앱 또는 라이브러리를 통해 지원됩니다.

Xamarin.Android 바인딩 라이브러리를 Android용 .NET 클래스 라이브러리로 마이그레이션하려면 다음을 수행합니다.

  1. Visual Studio에서 Xamarin.Android 바인딩 프로젝트와 동일한 이름으로 새 Android Java 라이브러리 바인딩 프로젝트를 만듭니다.

    Visual Studio에서 Android Java 라이브러리 바인딩 프로젝트를 만드는 스크린샷

    프로젝트 파일을 열면 .NET SDK 스타일 프로젝트가 있는지 확인합니다.

    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
        <TargetFramework>net8.0-android</TargetFramework>
        <SupportedOSPlatformVersion>21</SupportedOSPlatformVersion>
        <Nullable>enable</Nullable>
        <ImplicitUsings>enable</ImplicitUsings>
      </PropertyGroup>
    </Project>
    

    참고 항목

    Android 바인딩 라이브러리의 프로젝트 파일은 Android 클래스 라이브러리의 프로젝트 파일과 동일합니다.

  2. 프로젝트에 JAR(Java Archive) 또는 AAR(Android Archive)을 추가하고 빌드 작업이 AndroidLibrary설정되어 있는지 확인합니다.

  3. Xamarin.Android 바인딩 라이브러리에서 변환 또는 추가를 복사합니다.

지원되지 않는 레거시 옵션

다음 레거시 옵션은 더 이상 지원되지 않습니다. 지원되는 대안은 몇 년 동안 사용할 수 있으며 가장 원활한 마이그레이션 옵션은 .NET으로 마이그레이션하기 전에 이러한 옵션을 사용하여 현재 프로젝트를 업데이트하고 테스트하는 것입니다.

AndroidClassParser

jar2xml 가 더 이상 속성에 유효한 $(AndroidClassParser) 옵션이 아닙니다. class-parse 는 이제 기본 및 지원되는 옵션입니다.

class-parse 는 다음과 같이 사용할 수 jar2xml없는 많은 새로운 최신 기능을 활용합니다.

  • 클래스 메서드에 대한 자동 매개 변수 이름입니다(Java 코드가 컴파일된 javac -parameters경우).
  • Kotlin 지원.
  • DIM(정적/기본 인터페이스 멤버) 지원.
  • Java NRT(Nullable 참조 형식) 주석이 지원됩니다.

AndroidCodegenTarget

XamarinAndroid 가 더 이상 속성에 유효한 $(AndroidCodegenTarget) 옵션이 아닙니다. XAJavaInterop1 는 이제 기본 및 지원되는 옵션입니다.

생성된 바인딩 코드 Additions 와 상호 작용하는 파일에 손으로 바인딩된 코드가 있는 경우 호환 XAJavaInterop1되도록 업데이트해야 할 수 있습니다.

기본 파일 포함

다음 파일 구조가 지정된 경우:

Transforms/
    Metadata.xml
foo.jar

Transforms\*.xml파일은 자동으로 항목으로 @(TransformFile) 포함되고.aar .jar/파일은 항목으로 @(AndroidLibrary) 자동으로 포함됩니다. 그러면 .에서 Transforms\Metadata.xml메타데이터 수정을 사용하는 데 있는 Java 형식에 foo.jar 대한 C# 형식이 바인딩됩니다.

기본 Android 관련 파일 globbing 동작은 AutoImport.props에 정의되어 있습니다. 이 동작은 Android 항목에 대해 속성을 설정하여 사용하지 않도록 설정할 $(EnableDefaultAndroidItems) 수 있습니다. 또는 속성을 false설정하여 모든 기본 항목 포함 동작을 $(EnableDefaultItems) false사용하지 않도록 설정할 수 있습니다.

원치 .jar .aar 않거나 파일이 기본 wild카드s에 포함될 수 있습니다. 예를 들어 다음 C# 컴파일러 오류로 인해 AndroidStudio\gradle\wrapper\gradle-wrapper.jar 파일이 의도치 않게 바인딩됩니다.

Org.Gradle.Cli.AbstractCommandLineConverter.cs(11,89): error CS0535: 'Download' does not implement interface member 'IDownload.Download(URI, File)'
Org.Gradle.Wrapper.Download.cs(10,60): error CS0535: 'AbstractCommandLineConverter' does not implement interface member 'ICommandLineConverter.Convert(ParsedCommandLine, Object)'

이 문제를 해결하려면 프로젝트 파일에서 특정 파일을 제거할 수 있습니다.

<ItemGroup>
  <AndroidLibrary Remove="AndroidStudio\gradle\wrapper\gradle-wrapper.jar" />
</ItemGroup>

또는 폴더 내의 모든 파일을 제외할 수 있습니다.

<AndroidLibrary Remove="AndroidStudio\**\*" />

새 항목 그룹 이름

<AndroidLibrary> 는 이제 모든 .jar 파일과 파일에 사용할 권장 항목 그룹입니다 .aar . Xamarin.Android에서는 항목 메타데이터를 사용하여 동일한 결과를 얻을 수 있는 다음 항목 그룹이 사용되었습니다.

레거시 항목 그룹 새 항목 그룹 항목 메타데이터 레거시 프로젝트 형식
AndroidAarLibrary AndroidLibrary Bind="false" 애플리케이션
AndroidJavaLibrary AndroidLibrary Bind="false" 애플리케이션 또는 클래스 라이브러리
EmbeddedJar AndroidLibrary 해당 없음 바인딩 프로젝트
EmbeddedReferenceJar AndroidLibrary Bind="false" 바인딩 프로젝트
InputJar AndroidLibrary Pack="false" 바인딩 프로젝트
LibraryProjectZip AndroidLibrary 해당 없음 바인딩 프로젝트

.aar C# 바인딩을 포함하는 데 관심이 없는 파일 또는 .jar 파일을 고려합니다. 이는 C#에서 호출할 필요가 없는 Java 또는 Kotlin 종속성이 있는 경우에 일반적입니다. 이 경우 메타데이터falseBind .로 설정할 수 있습니다. 기본적으로 파일은 기본 wild카드s에 의해 선택됩니다. 특성을 사용하여 Update 메타데이터를 Bind 설정할 수도 있습니다.

<ItemGroup>
  <AndroidLibrary Update="foo.jar" Bind="false">
</ItemGroup>

Android 클래스 라이브러리 프로젝트에서는 결과 NuGet 패키지 내의 .jar 파일을 있는 그대로 재배포합니다. Android 애플리케이션 프로젝트에서 결과 또는 .aab 파일에 파일을 .apk 포함합니다.jar. 이 Java 라이브러리에 대한 C# 바인딩도 포함하지 않습니다.

포함된 JAR/AAR 파일

Xamarin.Android에서는 Java .jar 또는 .aar 바인딩 .dll 에 포함된 리소스로 포함되는 경우가 많습니다. 그러나 이로 인해 각각 .dll Java 코드를 열고 검사해야 하므로 빌드 속도가 느려졌습니다. 발견되면 사용할 디스크로 추출해야 합니다.

.NET에서 Java 코드는 더 이상 에 .dll포함되지 않습니다. 앱 빌드 프로세스에는 참조된 디렉터리와 동일한 디렉터리에서 찾은 파일 또는 .aar 파일이 자동으로 포함 .jar 됩니다.dll.

프로젝트가 바인딩을 통해 <PackageReference> 참조하는 경우 또는 <ProjectReference> 모든 것이 작동하며 추가 고려 사항이 필요하지 않습니다. 그러나 프로젝트에서 바인딩을 통해 <Reference>참조하는 경우 해당 바인딩은.aar .jar/옆에 .dll있어야 합니다. 즉, 다음 참조에 대해 다음과 같습니다.

<Reference Include="MyBinding.dll" />

다음 예제와 같은 디렉터리가 작동하지 않습니다.

lib/
    MyBinding.dll

대신 디렉터리에 네이티브 코드도 포함되어야 합니다.

lib/
    MyBinding.dll
    mybinding.jar

마이그레이션 고려 사항

Java에 더 잘 맞는 바인딩을 생성하는 데 도움이 되도록 기본적으로 설정된 몇 가지 새로운 기능이 있습니다. 그러나 기존 바인딩 프로젝트를 마이그레이션하는 경우 이러한 기능은 기존 바인딩과 호환되는 API가 아닌 바인딩을 만들 수 있습니다. 호환성을 기본 위해 이러한 새 기능을 사용하지 않도록 설정하거나 수정할 수 있습니다.

인터페이스 상수

일반적으로 C#에서는 Java에서 일반적인 패턴인 interface상수 선언을 허용하지 않았습니다.

public interface Foo {
     public static int BAR = 1;
}

이 패턴은 이전에 상수가 포함된 대안을 class 만들어 지원했습니다.

public abstract class Foo : Java.Lang.Object
{
   public static int Bar = 1;
}

C# 8에서는 이러한 상수가 다음 위치에 interface배치됩니다.

public interface IFoo
{
    public static int Bar = 1;
}

그러나 이는 기존 코드가 의존할 수 있는 대체 클래스가 더 이상 생성되지 않음을 의미합니다.

$(AndroidBoundInterfacesContainConstants) 프로젝트 파일에서 속성을 false 설정하면 레거시 동작으로 되돌리기.

중첩된 인터페이스 형식

일반적으로 C#에서는 Java에서 interface허용되는 중첩 형식을 선언할 수 없습니다.

public interface Foo {
     public class Bar { }
}

이 패턴은 인터페이스 및 중첩된 형식 이름으로 구성된 생성된 이름을 사용하여 중첩된 형식을 최상위 형식으로 이동하여 지원되었습니다.

public interface IFoo { }

public class IFooBar : Java.Lang.Object { }

C# 8을 사용하면 중첩된 형식을 다음 위치에 배치할 interface수 있습니다.

public interface IFoo
{
    public class Bar : Java.Lang.Object { }
}

그러나 이는 기존 코드가 의존할 수 있는 최상위 클래스가 더 이상 생성되지 않음을 의미합니다.

$(AndroidBoundInterfacesContainTypes) 프로젝트 파일에서 속성을 false 설정하면 레거시 동작으로 되돌리기.

예를 들어 하이브리드 방법을 사용하여 기존 중첩된 형식을 최상위 형식으로 이동하지만 이후 중첩된 형식이 다시 중첩되도록 허용하려는 경우기본 특성을 설정 unnest 하여 metadata 수준에서 이를 interface 지정할 수 있습니다. 이를 설정하면 true 중첩된 형식(레거시 동작)이 "중첩 해제"됩니다.

<attr path="/api/package[@name='my.package']/interface[@name='Foo']" name="unnest">true</attr>

이를 설정하면 false 중첩된 형식이 다시 기본(.NET 동작)에 interface 중첩됩니다.

<attr path="/api/package[@name='my.package']/interface[@name='Foo']" name="unnest">false</attr>

이 방법을 사용하면 속성을 그대로 두고 $(AndroidBoundInterfacesContainTypes) 현재 중첩된 형식의 true 모든 interface 항목에 대해 설정할 unnesttrue 있습니다. 이러한 형식은 항상 최상위 형식을 다시 기본, 나중에 도입된 새 중첩 형식은 중첩됩니다.

정적 및 기본 인터페이스 멤버(DIM)

일반적으로 C#에서는 인터페이스에 멤버 및 default 메서드를 포함 static 할 수 없습니다.

public interface Foo {
  public static void Bar () { ... }
  public default void Baz () { ... }
}

인터페이스의 정적 멤버는 형제 class로 이동하여 지원되었습니다.

public interface IFoo { }

public class Foo
{
    public static void Bar () { ... }
}

default 인터페이스 메서드는 필요하지 않고 이를 지원하는 C# 구문이 없었기 때문에 일반적으로 바인딩되지 않았습니다.

C# 8 staticdefault 멤버는 Java 인터페이스를 미러 인터페이스에서 지원됩니다.

public interface IFoo
{
    public static void Bar () { ... }
    public default void Baz () { ... }
}

그러나 이는 멤버를 포함하는 static 대체 형제 class 가 더 이상 생성되지 않음을 의미합니다.

$AndroidBoundInterfacesContainStaticAndDefaultInterfaceMethods 프로젝트 파일에서 속성을 false 설정하면 레거시 동작으로 되돌리기.

nullable 참조 형식

NRT(Nullable 참조 형식)에 대한 지원이 Xamarin.Android 11.0에 추가되었습니다. NRT 지원은 표준 .NET 메커니즘을 사용하여 사용하도록 설정할 수 있습니다.

<PropertyGroup>
  <Nullable>enable</Nullable>
</PropertyGroup>

.NET의 기본값은 disableXamarin.Android 프로젝트에도 동일하게 적용됩니다.

Resource.designer.cs

Xamarin.Android에서 Java 바인딩 프로젝트는 파일 생성을 Resource.designer.cs 지원하지 않았습니다. 바인딩 프로젝트는 .NET의 클래스 라이브러리일 뿐이므로 이 파일이 생성됩니다. 이는 기존 프로젝트를 마이그레이션할 때 호환성이 손상되는 변경일 수 있습니다.

이 변경으로 인한 오류의 한 가지 예는 바인딩이 루트 네임스페이스에 명명된 Resource 클래스를 생성하는 경우입니다.

error CS0101: The namespace 'MyBinding' already contains a definition for 'Resource'

또는 AndroidX의 경우 이름에 다음과 같은 androidx.window/window-extensions.csproj프로젝트 파일이 - 있습니다. 그러면 루트 네임스페이스가 window-extensions 생성되고 다음에서 C#이 잘못되었습니다.Resource.designer.cs

error CS0116: A namespace cannot directly contain members such as fields, methods or statements
error CS1514: { expected
error CS1022: Type or namespace definition, or end-of-file expected

생성을 사용하지 않도록 설정 Resource.designer.cs 하려면 프로젝트 파일에서 속성을 false 설정합니다$(AndroidGenerateResourceDesigner).

<PropertyGroup>
  <AndroidGenerateResourceDesigner>false</AndroidGenerateResourceDesigner>
</PropertyGroup>