Sdílet prostřednictvím


Migrace projektu vazby Xamarin.Android

V .NET neexistuje žádný koncept projektu vazby Pro Android jako samostatného typu projektu. Všechny skupiny položek MSBuild nebo akce sestavení, které fungují v projektech vazeb Xamarin.Android, jsou podporovány prostřednictvím aplikace nebo knihovny .NET pro Android.

Migrace knihovny vazeb Xamarin.Android do knihovny tříd .NET pro Android:

  1. V sadě Visual Studio vytvořte nový projekt vazby knihovny Android Java se stejným názvem jako projekt vazby Xamarin.Android:

    Snímek obrazovky vytvoření projektu vazby knihovny Android Java v sadě Visual Studio

    Otevřením souboru projektu potvrdíte, že máte projekt ve stylu sady .NET SDK:

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

    Poznámka:

    Soubor projektu pro knihovnu vazeb pro Android je stejný jako soubor projektu pro knihovnu tříd Androidu.

  2. Přidejte do projektu soubor Java Archive (JAR) nebo AAR (Android Archive) a ujistěte se, že je jeho akce sestavení nastavená na AndroidLibrary.

  3. Zkopírujte všechny transformace nebo doplňky z knihovny vazeb Xamarin.Android.

Nepodporované starší možnosti

Následující starší verze už nejsou podporované. Podporované alternativy jsou k dispozici několik let a nejhladší možností migrace je aktualizovat a otestovat aktuální projekty s těmito možnostmi před jejich migrací na .NET.

AndroidClassParser

jar2xml již není platná možnost vlastnosti $(AndroidClassParser) . class-parse je teď výchozí a pouze podporovaná možnost.

class-parse využívá mnoho nových moderních funkcí, které nejsou k dispozici, jar2xmlnapříklad:

  • Automatické názvy parametrů pro metody tříd (pokud je kód Java zkompilován pomocí javac -parameters).
  • Podpora Kotlinu.
  • Podpora člena statického nebo výchozího rozhraní (DIM).
  • Podpora poznámek k referenčnímu typu NRT (Java Nullable).

AndroidCodegenTarget

XamarinAndroid již není platná možnost vlastnosti $(AndroidCodegenTarget) . XAJavaInterop1 je teď výchozí a pouze podporovaná možnost.

Pokud máte v Additions souborech ručně svázaný kód, který komunikuje s vygenerovaným kódem vazby, bude možná potřeba ho aktualizovat, aby byl kompatibilní s XAJavaInterop1.

Výchozí zahrnutí souborů

Vzhledem k následující struktuře souborů:

Transforms/
    Metadata.xml
foo.jar

Transforms\*.xml soubory se automaticky zahrnou @(TransformFile) jako položka a .jar/.aar soubory se automaticky zahrnou @(AndroidLibrary) jako položka. Tím se vytvoří vazba typů jazyka C# pro typy Javy nalezené při foo.jar použití oprav metadat z Transforms\Metadata.xml.

Výchozí chování souboru souvisejícího s Androidem je definováno v autoImport.props. Toto chování lze pro položky Androidu zakázat nastavením $(EnableDefaultAndroidItems) vlastnosti na falsehodnotu , nebo je možné zakázat chování zahrnutí všech výchozích položek nastavením $(EnableDefaultItems) vlastnosti na falsehodnotu .

.jar Nežádoucí soubory nebo .aar soubory můžou být součástí výchozích zástupných znaků. Například následující chyby kompilátoru jazyka C# jsou výsledkem neúmyslně vázaného AndroidStudio\gradle\wrapper\gradle-wrapper.jar souboru:

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

Pokud chcete tento problém vyřešit, můžete konkrétní soubor v souboru projektu odebrat:

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

Případně můžete vyloučit všechny soubory ve složce:

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

Názvy nových skupin položek

<AndroidLibrary> je teď doporučená skupina položek, která se má použít pro všechny .jar soubory a .aar soubory. V Xamarin.Androidu byly použity následující skupiny položek, které místo toho můžou použít metadata položek k dosažení stejného výsledku:

Skupina starších položek Nová skupina položek Metadata položek Starší typ projektu
AndroidAarLibrary AndroidLibrary Bind="false" Aplikace
AndroidJavaLibrary AndroidLibrary Bind="false" Knihovna aplikací nebo tříd
EmbeddedJar AndroidLibrary Není k dispozici Vytvoření vazby projektu
EmbeddedReferenceJar AndroidLibrary Bind="false" Vytvoření vazby projektu
InputJar AndroidLibrary Pack="false" Vytvoření vazby projektu
LibraryProjectZip AndroidLibrary Není k dispozici Vytvoření vazby projektu

.aar Zvažte nebo .jar vytvořte soubor, ve kterém nemáte zájem o zahrnutí vazby jazyka C#. To je běžné v případech, kdy máte závislosti Java nebo Kotlin, které nepotřebujete volat z jazyka C#. V tomto případě můžete nastavit Bind metadata na false. Ve výchozím nastavení se soubor vyzvedne pomocí výchozích zástupných znaků. Pomocí atributu UpdateBind můžete také nastavit metadata:

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

V projektu knihovny tříd pro Android by se soubor redistribuoval .jar uvnitř výsledného balíčku NuGet tak, jak je. V projektu aplikace pro Android by to zahrnovalo .jar soubor do výsledného .apk souboru nebo .aab souboru. Žádná z nich nezahrnuje vazbu jazyka C# pro tuto knihovnu Java.

Vložené soubory JAR/AAR

V Xamarin.Androidu byla Java .jar nebo .aar často vložena do vazby .dll jako vložený prostředek. To však vedlo k pomalým sestavením, protože každý z nich .dll musí být otevřen a prohledáván kód Java. Pokud se najde, musí se extrahovat na disk, který se má použít.

V .NET už kód Java není vložen do .dllsouboru . Proces sestavení aplikace automaticky zahrne všechny .jar soubory nebo .aar soubory, které najde ve stejném adresáři jako odkazovaný .dll.

Pokud projekt odkazuje na vazbu prostřednictvím <PackageReference> vazby nebo <ProjectReference> pak všechno funguje a nejsou potřeba žádné další aspekty. Pokud však projekt odkazuje na vazbu prostřednictvím <Reference>,.aar.jar/musí být umístěn vedle ..dll To znamená, že pro následující odkaz:

<Reference Include="MyBinding.dll" />

Adresář podobný adresáři v následujícím příkladu nebude fungovat:

lib/
    MyBinding.dll

Místo toho musí adresář obsahovat také nativní kód:

lib/
    MyBinding.dll
    mybinding.jar

Posouzení migrace

Ve výchozím nastavení je několik nových funkcí, které pomáhají vytvářet vazby, které lépe odpovídají jejich protějškům v Javě. Pokud ale migrujete existující projekt vazeb, mohou tyto funkce vytvářet vazby, které nejsou kompatibilní s vašimi existujícími vazbami. Chcete-li zachovat kompatibilitu, můžete tyto nové funkce zakázat nebo upravit.

Konstanty rozhraní

Tradičně jazyk C# nepovolil deklaraci konstant v jazyce interface, což je běžný vzor v Javě:

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

Tento model byl dříve podporován vytvořením alternativy class , která obsahuje konstanty:

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

V jazyce C# 8 jsou tyto konstanty umístěny na interface:

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

To však znamená, že alternativní třída, na které existující kód může záviset, se už nevygeneruje.

$(AndroidBoundInterfacesContainConstants) Nastavení vlastnosti v false souboru projektu se vrátí k chování starší verze.

Vnořené typy rozhraní

Tradičně jazyk C# nepovolil deklaraci vnořených typů v jazyce interfaceJava, který je povolený v Javě:

public interface Foo {
     public class Bar { }
}

Tento model byl podporován přesunutím vnořeného typu na typ nejvyšší úrovně s vygenerovaným názvem složeným z rozhraní a vnořeným názvem typu:

public interface IFoo { }

public class IFooBar : Java.Lang.Object { }

V jazyce C# 8 lze vnořené typy umístit do interface:

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

To však znamená, že třída nejvyšší úrovně, na které může stávající kód záviset, se už negeneruje.

$(AndroidBoundInterfacesContainTypes) Nastavení vlastnosti v false souboru projektu se vrátí k chování starší verze.

Pokud chcete použít hybridní přístup, například pokud chcete zachovat stávající vnořené typy přesunuté na typ nejvyšší úrovně, ale umožnit, aby budoucí vnořené typy zůstaly vnořené, můžete ho zadat na interface úrovni pomocí metadata nastavení atributu unnest . Pokud ho nastavíte tak true , aby se vnořily všechny vnořené typy (chování starší verze):

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

Pokud ho interface nastavíte takfalse, aby vnořené typy zůstaly vnořené v chování (.NET):

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

Pomocí tohoto přístupu můžete nechat vlastnost nastavenou $(AndroidBoundInterfacesContainTypes) tak, aby truetrue byla nastavena unnest pro každý interface s vnořenými typy, které aktuálně máte. Tyto typy zůstanou vždy nejvyšší úrovně, zatímco všechny nové vnořené typy zavedené později budou vnořené.

Statické a výchozí členy rozhraní (DIM)

Tradičně jazyk C# nepovolil rozhraní, která by obsahovala static členy a default metody:

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

Statické členy na rozhraních podporují jejich přesunutím na stejné rozhraní class:

public interface IFoo { }

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

default metody rozhraní tradičně nebyly vázány, protože nejsou povinné a nebyl k dispozici konstruktor jazyka C#, který je podporuje.

S C# 8 static a default členy jsou podporovány v rozhraních, zrcadlení rozhraní Java:

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

To však znamená, že se už nevygeneruje alternativní seznam na stejné straně class obsahující static členy.

$AndroidBoundInterfacesContainStaticAndDefaultInterfaceMethods Nastavení vlastnosti v false souboru projektu se vrátí k chování starší verze.

Odkazové typy s možnou hodnotou null

V Xamarin.Androidu 11.0 byla přidána podpora typů odkazů s možnou hodnotou Null (NRT). Podporu NRT je možné povolit pomocí standardního mechanismu .NET:

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

Vzhledem k tomu, že výchozí hodnota pro .NET je disable, platí totéž pro projekty Xamarin.Android.

Resource.designer.cs

V Xamarin.Androidu projekty vazeb Java nepodporují generování Resource.designer.cs souboru. Vzhledem k tomu, že vazbové projekty jsou pouze knihovny tříd v .NET, tento soubor se vygeneruje. Při migraci stávajících projektů to může být zásadní změna.

Jedním z příkladů selhání z této změny je, že vaše vazba vygeneruje třídu pojmenovanou Resource v kořenovém oboru názvů:

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

Nebo v případě AndroidX existují soubory projektu s - názvem, například androidx.window/window-extensions.csproj. Výsledkem je kořenový obor názvů a neplatný jazyk window-extensions C# v 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

Pokud chcete generování zakázat Resource.designer.cs , nastavte $(AndroidGenerateResourceDesigner) vlastnost do false souboru projektu:

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