.NET では、別のプロジェクトの種類として Android バインド プロジェクトの概念はありません。 Xamarin.Android バインド プロジェクトで動作する MSBuild 項目グループまたはビルド アクションは、.NET for Android アプリまたはライブラリを通じてサポートされます。
Xamarin.Android バインド ライブラリを .NET for Android クラス ライブラリに移行するには:
Visual Studio で、Xamarin.Android バインド プロジェクトと同じ名前の新しい 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 クラス ライブラリのプロジェクト ファイルと同じです。
Java Archive (JAR) または Android Archive (AAR) をプロジェクトに追加し、そのビルド アクションが AndroidLibrary に設定されていることを確認します。
Xamarin.Android バインド ライブラリから変換または追加をコピーします。
サポートされていないレガシ オプション
次の従来のオプションはサポートされなくなりました。 サポートされている代替手段は数年間使用できます。最もスムーズな移行オプションは、.NET に移行する前に、これらのオプションを使用して現在のプロジェクトを更新してテストすることです。
AndroidClassParser
jar2xml
は、 $(AndroidClassParser)
プロパティの有効なオプションではなくなりました。 class-parse
が既定のオプションであり、サポートされているオプションのみです。
class-parse
では、次のような、 jar2xml
では使用できない多くの新しいモダン機能を利用しています。
- クラス メソッドの自動パラメーター名 (Java コードが
javac -parameters
でコンパイルされている場合)。 - Kotlin のサポート。
- 静的/既定のインターフェイス メンバー (DIM) のサポート。
- Java nullable 参照型 (NRT) 注釈をサポートします。
AndroidCodegenTarget
XamarinAndroid
は、 $(AndroidCodegenTarget)
プロパティの有効なオプションではなくなりました。 XAJavaInterop1
が既定のオプションであり、サポートされているオプションのみです。
生成されたバインド コードと対話する Additions
ファイルにハンドバインド コードがある場合は、 XAJavaInterop1
と互換性を持つよう更新する必要がある場合があります。
既定のファイル インクルード
次のファイル構造を指定します。
Transforms/
Metadata.xml
foo.jar
Transforms\*.xml
ファイルは @(TransformFile)
項目として自動的に含まれるほか、 .jar
/.aar
ファイルは自動的に @(AndroidLibrary)
項目として含まれます。 Transforms\Metadata.xml
のメタデータ修正を使用して、foo.jar
で見つかった Java 型に C# 型をバインドします。
既定の Android 関連ファイルの globbing 動作は 、AutoImport.props で定義されています。 この動作は、 $(EnableDefaultAndroidItems)
プロパティを false
に設定することで Android アイテムで無効にできます。または、 $(EnableDefaultItems)
プロパティを false
に設定することで、すべての既定の項目包含動作を無効にすることができます。
望ましくない .jar
または .aar
ファイルを既定のワイルドカードに含めることもできます。 たとえば、次の 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 |
n/a | プロジェクトの結合 |
EmbeddedReferenceJar |
AndroidLibrary |
Bind="false" |
バインディングプロジェクト |
InputJar |
AndroidLibrary |
Pack="false" |
バインド プロジェクト |
LibraryProjectZip |
AndroidLibrary |
n/a | バインド プロジェクト |
C# バインディングを含めるのに関心がない .aar
または .jar
ファイルについて考えてみましょう。 これは、C# から呼び出す必要のない Java または Kotlin の依存関係がある場合に一般的です。 この場合、 Bind
メタデータを false
に設定できます。 既定では、ファイルは既定のワイルドカードによって取得されます。 Update
属性を使用して、Bind
メタデータを設定することもできます。
<ItemGroup>
<AndroidLibrary Update="foo.jar" Bind="false">
</ItemGroup>
Android クラス ライブラリ プロジェクトでは、結果の NuGet パッケージ内の .jar
ファイルをそのまま再配布します。 Android アプリケーション プロジェクトでは、結果の.apk
または.aab
ファイルに.jar
ファイルが含まれます。 この Java ライブラリの C# バインドも含まれていません。
埋め込み JAR/AAR ファイル
Xamarin.Android では、Java .jar
または .aar
は、多くの場合、埋め込みリソースとしてバインド .dll
に埋め込まれています。 ただし、これにより、各 .dll
を開いて Java コードをスキャンする必要があり、ビルドが遅くなります。 見つかった場合は、使用するディスクに抽出する必要があります。
.NET では、Java コードは .dll
に埋め込まれなくなりました。 アプリのビルド プロセスには、参照先の.dll
と同じディレクトリにある.jar
または.aar
ファイルが自動的に含まれます。
プロジェクトが <PackageReference>
または <ProjectReference>
を介してバインドを参照する場合、すべてが機能し、追加の考慮事項は必要ありません。 ただし、プロジェクトが <Reference>
を介してバインドを参照する場合、 .jar
/.aar
は .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
に設定すると、従来の動作に戻ります。
ハイブリッドアプローチを使用する場合、たとえば、既存のネストされた型を最上位の型に移動しつつ、将来的に新たにネストされた型はそのままネストされた状態にしておきたい場合、これはinterface
レベルで指定でき、metadata
を使用してunnest
属性を設定します。 これを true
に設定すると、入れ子になった型が "入れ子でなくなります" (以前の動作)。
<attr path="/api/package[@name='my.package']/interface[@name='Foo']" name="unnest">true</attr>
false
に設定すると、入れ子になっている型はinterface
にとどまり、これは.NETの動作です。
<attr path="/api/package[@name='my.package']/interface[@name='Foo']" name="unnest">false</attr>
この方法を使用すると、$(AndroidBoundInterfacesContainTypes)
プロパティをtrue
のままにし、現在の入れ子になった型を持つすべてのinterface
に対してunnest
をtrue
に設定できます。 これらは常に最上位レベルの型として維持されますが、後で導入される新しい入れ子型はネストされます。
静的および既定のインターフェイス メンバー (DIM)
従来、C# では、インターフェイスに static
メンバーと default
メソッドを含めることはできません。
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 では、インターフェイスで static
メンバーと default
メンバーがサポートされ、Java インターフェイスがミラーリングされます。
public interface IFoo
{
public static void Bar () { ... }
public default void Baz () { ... }
}
ただし、これは、static
メンバーを含む代替兄弟class
が生成されなくなるということです。
$AndroidBoundInterfacesContainStaticAndDefaultInterfaceMethods
プロパティをプロジェクト ファイルでfalse
に設定すると、従来の動作に戻ります。
null 許容参照型
Xamarin.Android 11.0 で Null 許容参照型 (NRT) のサポートが追加されました。 NRT のサポートは、標準の .NET メカニズムを使用して有効にすることができます。
<PropertyGroup>
<Nullable>enable</Nullable>
</PropertyGroup>
.NET の既定値は disable
であるため、Xamarin.Android プロジェクトにも同じことが適用されます。
Resource.designer.cs
Xamarin.Android では、Java バインド プロジェクトでは、 Resource.designer.cs
ファイルの生成はサポートされていませんでした。 バインド プロジェクトは .NET のクラス ライブラリに過ぎないため、このファイルが生成されます。 これは、既存のプロジェクトを移行するときに重大な変更になる可能性があります。
この変更によるエラーの 1 つの例は、バインドによってルート名前空間に Resource
という名前のクラスが生成される場合です。
error CS0101: The namespace 'MyBinding' already contains a definition for 'Resource'
または、AndroidX の場合、androidx.window/window-extensions.csproj
などの名前に-
を持つプロジェクト ファイルがあります。 これにより、ルート名前空間が window-extensions
され、 Resource.designer.cs
の C# が無効になります。
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
生成を無効にするには、プロジェクト ファイルで $(AndroidGenerateResourceDesigner)
プロパティをfalse
に設定します。
<PropertyGroup>
<AndroidGenerateResourceDesigner>false</AndroidGenerateResourceDesigner>
</PropertyGroup>
.NET MAUI