Aracılığıyla paylaş


Xamarin.Android bağlama projesi geçişi

.NET'te, ayrı bir proje türü olarak Android bağlama projesi kavramı yoktur. Xamarin.Android bağlama projelerinde çalışan MSBuild öğe gruplarından veya derleme eylemlerinden herhangi biri, Android için .NET uygulaması veya kitaplığı aracılığıyla desteklenir.

Xamarin.Android bağlama kitaplığını Android için .NET sınıf kitaplığına geçirmek için:

  1. Visual Studio'da, Xamarin.Android bağlama projenizle aynı ada sahip yeni bir Android Java Kitaplığı Bağlama projesi oluşturun:

    Visual Studio'da Android Java Kitaplığı Bağlama projesi oluşturma işleminin ekran görüntüsü.

    Proje dosyasını açtığınızda .NET SDK stilinde bir projeniz olduğunu onaylar:

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

    Not

    Android bağlama kitaplığının proje dosyası, Android sınıf kitaplığının proje dosyasıyla aynıdır.

  2. Projeye Java Arşivi (JAR) veya Android Arşivi (AAR) ekleyin ve derleme eyleminin AndroidLibrary olarak ayarlandığından emin olun.

  3. Xamarin.Android bağlama kitaplığınızdan tüm dönüştürmeleri veya eklemeleri kopyalayın.

Desteklenmeyen eski seçenekler

Aşağıdaki eski seçenekler artık desteklenmiyor. Desteklenen alternatifler birkaç yıldır kullanılabilir ve en sorunsuz geçiş seçeneği, geçerli projelerinizi .NET'e geçirmeden önce bu seçeneklerle güncelleştirmek ve test etmektir.

AndroidClassParser

jar2xml özelliği için $(AndroidClassParser) artık geçerli bir seçenek değildir. class-parse artık varsayılan ve yalnızca desteklenen seçenektir.

class-parse , içinde jar2xmlbulunmayan birçok yeni modern özelliğin avantajlarından yararlanır, örneğin:

  • Sınıf yöntemleri için otomatik parametre adları (Java kodunuz ile javac -parametersderlenmişse).
  • Kotlin desteği.
  • Statik/varsayılan arabirim üyesi (DIM) desteği.
  • Java Null atanabilir başvuru türü (NRT) ek açıklamaları desteği.

AndroidCodegenTarget

XamarinAndroid özelliği için $(AndroidCodegenTarget) artık geçerli bir seçenek değildir. XAJavaInterop1 artık varsayılan ve yalnızca desteklenen seçenektir.

Dosyalarınızda oluşturulan bağlama koduyla etkileşim kuran el ile bağlı kodunuz Additions varsa, ile XAJavaInterop1uyumlu olacak şekilde güncelleştirilmiş olması gerekebilir.

Varsayılan dosya ekleme

Aşağıdaki dosya yapısı göz önünde bulundurulduğunda:

Transforms/
    Metadata.xml
foo.jar

Transforms\*.xmldosyalar otomatik olarak bir @(TransformFile) öğe olarak eklenir ve.aar.jar/dosyalar otomatik olarak öğe @(AndroidLibrary) olarak eklenir. Bu, içindeki meta veri düzeltmelerini Transforms\Metadata.xmlkullanarak içinde foo.jar bulunan Java türleri için C# türlerini bağlar.

Varsayılan Android ile ilgili dosya globbing davranışı AutoImport.props içinde tanımlanır. Bu davranış, Özelliği olarak ayarlanarak $(EnableDefaultAndroidItems) Android öğeleri için devre dışı bırakılabilir veya tüm varsayılan öğe ekleme davranışı özelliği falseolarak ayarlanarak $(EnableDefaultItems) devre dışı bırakılabilir.false

.jar Istenmeyen veya .aar dosyalar varsayılan joker karakterlere dahil edilebilir. Örneğin, aşağıdaki C# derleyici hataları bir AndroidStudio\gradle\wrapper\gradle-wrapper.jar dosyanın istemeden bağlı olmasına neden olur:

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)'

Bu sorunu çözmek için proje dosyanızdaki belirli dosyayı kaldırabilirsiniz:

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

Alternatif olarak, bir klasördeki tüm dosyaları dışlayabilirsiniz:

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

Yeni öğe grubu adları

<AndroidLibrary> artık tüm .jar dosyalar ve .aar dosyalar için kullanılması önerilen öğe grubudur. Xamarin.Android'de, aynı sonucu elde etmek için öğe meta verilerini kullanabilen aşağıdaki öğe grupları kullanılmıştır:

Eski Öğe Grubu Yeni Öğe Grubu Öğe Meta Verileri Eski Proje Türü
AndroidAarLibrary AndroidLibrary Bind="false" Uygulama
AndroidJavaLibrary AndroidLibrary Bind="false" Uygulama veya sınıf kitaplığı
EmbeddedJar AndroidLibrary yok Projeyi bağlama
EmbeddedReferenceJar AndroidLibrary Bind="false" Projeyi bağlama
InputJar AndroidLibrary Pack="false" Projeyi bağlama
LibraryProjectZip AndroidLibrary yok Projeyi bağlama

.aar C# bağlaması eklemek istemediğiniz bir veya .jar dosyasını göz önünde bulundurun. Bu, C# dilinden çağırmanız gerekmeyen Java veya Kotlin bağımlılıklarınız olduğu durumlarda yaygındır. Bu durumda, meta verileri olarak falseayarlayabilirsinizBind. Varsayılan olarak, dosya varsayılan joker karakterler tarafından alınır. Meta verileri ayarlamak için özniteliğini UpdateBind de kullanabilirsiniz:

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

Bir Android sınıf kitaplığı projesinde, bu işlem sonucunda elde edilen NuGet paketinin içindeki dosyayı olduğu gibi yeniden dağıtır .jar . Bir Android uygulama projesinde.jar, sonuç veya .aab dosyaya .apk dosya dahil olur. Bu Java kitaplığı için C# bağlaması da dahil değildir.

Katıştırılmış JAR/AAR dosyaları

Xamarin.Android'de Java .jar veya .aar genellikle bağlamaya .dll Katıştırılmış Kaynak olarak eklenmişti. Ancak bu, her .dll birinin Java kodu için açılması ve taranması gerektiğinden yavaş derlemelere yol açtı. Bulunursa, kullanılması için diske ayıklanması gerekir.

.NET'te Java kodu artık içine eklenmez .dll. Uygulama derleme işlemi, başvurulan .dllile aynı dizinde bulduğu herhangi .jar bir veya .aar dosyayı otomatik olarak içerir.

Bir proje veya aracılığıyla <PackageReference> bağlamaya başvuruyorsa, <ProjectReference> her şey çalışır ve ek dikkate alınması gerekmez. Ancak, bir proje aracılığıyla <Reference>bağlamaya başvuruyorsa, öğesinin.aar.jar/.dllyanında bulunması gerekir. Yani, aşağıdaki başvuru için:

<Reference Include="MyBinding.dll" />

Aşağıdaki örnekteki gibi bir dizin çalışmaz:

lib/
    MyBinding.dll

Bunun yerine, dizinin yerel kodu da içermesi gerekir:

lib/
    MyBinding.dll
    mybinding.jar

Geçiş fikirleri

Java karşılıklarıyla daha iyi eşleşen bağlamalar üretmeye yardımcı olmak için varsayılan olarak ayarlanmış birkaç yeni özellik vardır. Ancak, var olan bir bağlama projesini geçiriyorsanız, bu özellikler mevcut bağlamalarınızla uyumlu API uyumlu olmayan bağlamalar oluşturabilir. Uyumluluğu korumak için bu yeni özellikleri devre dışı bırakmak veya değiştirmek isteyebilirsiniz.

Arabirim sabitleri

Geleneksel olarak, C# Java'da yaygın bir desen olan bir interfaceiçinde sabitlerin bildirilmesine izin vermemiştir:

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

Bu desen daha önce sabitleri içeren bir alternatif class oluşturularak destekleniyordu:

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

C# 8 ile bu sabitler üzerine interfaceyerleştirilir:

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

Ancak bu, mevcut kodun bağımlı olabileceği alternatif sınıfın artık oluşturulmayabileceği anlamına gelir.

$(AndroidBoundInterfacesContainConstants) Özelliğini proje dosyanızda olarak false ayarlamak eski davranışa geri döner.

İç içe arabirim türleri

Geleneksel olarak, C# java'da izin verilen iç içe türlerin içinde interfacebildirilmesine izin vermez:

public interface Foo {
     public class Bar { }
}

Bu düzen, iç içe türü arabirimden ve iç içe tür adından oluşturulmuş bir adla en üst düzey türe taşıyarak desteklendi:

public interface IFoo { }

public class IFooBar : Java.Lang.Object { }

C# 8 ile iç içe türler içine interfaceyerleştirilebilir:

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

Ancak bu, mevcut kodun bağımlı olabileceği en üst düzey sınıfın artık oluşturulmadığını gösterir.

$(AndroidBoundInterfacesContainTypes) Özelliğini proje dosyanızda olarak false ayarlamak eski davranışa geri döner.

Örneğin, var olan iç içe türlerin üst düzey bir türe taşınmasını sağlamak, ancak gelecekteki iç içe geçmiş türlerin iç içe kalmasına izin vermek için karma bir yaklaşım kullanmak istiyorsanız, özniteliğini ayarlamak unnest için kullanarak metadata düzeyinde bunu interface belirtebilirsiniz. olarak true ayarlanması, iç içe yerleştirilmiş türlerin (eski davranış) "iç içe kullanılmaması" ile sonuçlanır:

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

olarak false ayarlanması, iç içe türlerin interface (.NET davranışı) iç içe kalmasına neden olur:

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

Bu yaklaşımı kullanarak özelliğini olarak bırakabilir $(AndroidBoundInterfacesContainTypes) ve şu anda sahip olduğunuz iç içe türleri olan her interface için olarak ayarlayabilirsiniz unnesttrue.true Bunlar her zaman en üst düzey türler olarak kalırken, daha sonra kullanıma sunulan yeni iç içe türler iç içe yerleştirilmiş olur.

Statik ve varsayılan arabirim üyeleri (DIM)

C# geleneksel olarak arabirimlerin üyeleri ve default yöntemleri içermesine static izin vermez:

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

Arabirimlerdeki statik üyeler eşdüzey classbir öğeye taşınarak desteklenmiştir:

public interface IFoo { }

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

default arabirim yöntemleri gerekli olmadığından ve bunları destekleyecek bir C# yapısı olmadığından geleneksel olarak bağlı değildir.

C# 8 static ile ve default java arabirimini yansıtan arabirimlerde üyeler desteklenir:

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

Ancak bu, üyeleri içeren alternatif eşdüzeyin classstatic artık oluşturulacağı anlamına gelir.

$AndroidBoundInterfacesContainStaticAndDefaultInterfaceMethods Özelliğini proje dosyanızda olarak false ayarlamak eski davranışa geri döner.

Boş değer atanabilir başvuru türleri

Xamarin.Android 11.0'da Null Atanabilir Başvuru Türleri (NRT) desteği eklendi. NRT desteği standart .NET mekanizması kullanılarak etkinleştirilebilir:

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

.NET için varsayılan değer olduğundan disable, aynı durum Xamarin.Android projeleri için de geçerlidir.

Resource.designer.cs

Xamarin.Android'de Java bağlama projeleri dosya Resource.designer.cs oluşturmayı desteklemedi. Bağlama projeleri yalnızca .NET'teki sınıf kitaplıkları olduğundan, bu dosya oluşturulur. Bu, mevcut projeleri geçirirken hataya neden olan bir değişiklik olabilir.

Bu değişiklikten kaynaklanan bir hata örneği, bağlamanızın kök ad alanında adlı Resource bir sınıf oluşturmasıdır:

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

Veya AndroidX söz konusu olduğunda, adında gibi androidx.window/window-extensions.csprojproje - dosyaları vardır. Bu, kök ad alanına window-extensions ve içinde geçersiz C# ile sonuçlanmaktadır 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

Oluşturma özelliğini devre dışı bırakmak Resource.designer.cs için false proje dosyanızda olarak ayarlayın$(AndroidGenerateResourceDesigner):

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