Xamarin.Android project migration
A .NET 8 project for a .NET for Android app is similar to the following example:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0-android</TargetFramework>
<OutputType>Exe</OutputType>
</PropertyGroup>
</Project>
For a library project, omit the $(OutputType)
property completely or specify Library
as the property value.
.NET configuration files
There's no support for configuration files such as Foo.dll.config
or Foo.exe.config
in .NET for Android projects. <dllmap>
configuration elements aren't supported in .NET Core at all, and other element types for compatibility packages like System.Configuration.ConfigurationManager have never been supported in Android projects.
Changes to MSBuild properties
The $(AndroidSupportedAbis)
property shouldn't be used:
<PropertyGroup>
<!-- Used in Xamarin.Android projects -->
<AndroidSupportedAbis>armeabi-v7a;arm64-v8a;x86;x86_64</AndroidSupportedAbis>
</PropertyGroup>
Instead, the $(AndroidSupportedAbis)
property should be replaced with .NET runtime identifiers:
<PropertyGroup>
<!-- Used in .NET for Android projects -->
<RuntimeIdentifiers>android-arm;android-arm64;android-x86;android-x64</RuntimeIdentifiers>
</PropertyGroup>
For more information about runtime identifiers, see .NET RID Catalog.
The following table shows other MSBuild properties that have changed in .NET for Android:
Property | Comments |
---|---|
$(AndroidUseIntermediateDesignerFile) |
True by default. |
$(AndroidBoundExceptionType) |
System by default. This property alters the types of exceptions thrown from various methods to better align with .NET semantics, at the cost of compatibility with Xamarin.Android. For more information, see Some of the new wrapped Java exceptions use BCL exceptions that differ from the related BCL types. |
$(AndroidClassParser) |
class-parse by default. jar2xml isn't supported. |
$(AndroidDexTool) |
d8 by default. dx isn't supported. |
$(AndroidCodegenTarget) |
XAJavaInterop1 by default. XamarinAndroid isn't supported. |
$(AndroidManifest) |
Defaults to AndroidManifest.xml in the root of projects because Properties\AssemblyInfo.cs is no longer used in SDK-style projects. Properties\AndroidManifest.xml will also be detected and used if it exists, to ease migration. |
$(DebugType) |
portable by default. full and pdbonly aren't supported. |
$(MonoSymbolArchive) |
False , since mono-symbolicate isn't supported. |
In addition, if Java binding is enabled with @(InputJar)
, @(EmbeddedJar)
, or @(LibraryProjectZip)
, then the $(AllowUnsafeBlocks)
property defaults to True
.
Note
Referencing an Android Wear project from an Android app isn't supported.
Changes to AndroidManifest.xml
In Xamarin.Android, Java, and Kotlin Android projects, the <uses-sdk/>
element denotes the minimum Android version your app supports, as well as the target Android version your app is compiled against:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1"
android:versionName="1.0"
package="com.companyname.myapp">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="33" />
<application android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" />
</manifest>
For more information about the <uses-sdk/>
element, see the Android documentation.
In .NET 8 Android apps, there are MSBuild properties to set these values. Using the MSBuild properties has other benefits. In most cases the <uses-sdk/>
element should be removed in favor of values in your project's .csproj
file:
<Project>
<PropertyGroup>
<TargetFramework>net8.0-android</TargetFramework>
<SupportedOSPlatformVersion>21</SupportedOSPlatformVersion>
</PropertyGroup>
</Project>
In this example, net8.0-android
is shorthand for net8.0-android34.0
. Future versions of .NET will track the latest Android version available at the time of the .NET release.
TargetFramework
maps to android:targetSdkVersion
. At build time, this value will automatically be included in the <uses-sdk/>
element for you. The benefit of using TargetFramework
in this way is that you're given the matching C# binding for Android API 34 for net8.0-android34.0
. Android releases independently of the .NET release cycle, so we have the flexibility to opt into net8.0-android35.0
when a binding is available for the next Android release.
Similarly, SupportedOSPlatformVersion
maps to android:minSdkVersion
. At build time, this value will automatically be included in the <uses-sdk/>
element for you. Android APIs are decorated with the SupportedOSPlatformAttribute so that you get build warnings for calling APIs that are only available for some of the Android versions your app can run on:
error CA1416: This call site is reachable on 'Android' 21.0 and later. `ConnectivityManager.ActiveNetwork` is only supported on: 'Android' 23.0 and later.
To safely use this API, you can declare a higher SupportedOSPlatformVersion
in your project or use the IsAndroidVersionAtLeast API at runtime:
if (OperatingSystem.IsAndroidVersionAtLeast(23))
{
// Use the API here
}
Default file inclusion
Default .NET for Android related file globbing behavior is defined in AutoImport.props
. This behavior can be disabled for Android items by setting $(EnableDefaultAndroidItems)
to false
, or all default item inclusion behavior can be disabled by setting $(EnableDefaultItems)
to false
. For more information, see Workload props files.
Runtime behavior
There are behavioral changes to the String.IndexOf()
method in .NET 5+ on different platforms. For more information, see .NET globalization and ICU.
Linker
.NET 8 has new settings for the linker:
<PublishTrimmed>true</PublishTrimmed>
<TrimMode>partial</TrimMode>
, which trims assemblies that have opted-in to trimming.
For more information, see Trimming options.
In .NET for Android projects by default, Debug
builds don't use the linker, and Release
builds set PublishTrimmed=true
and TrimMode=partial
.
If the legacy AndroidLinkMode
setting is used, both SdkOnly
and Full
default to equivalent linker settings:
<PublishTrimmed>true</PublishTrimmed>
<TrimMode>partial</TrimMode>
With AndroidLinkMode=SdkOnly
, only BCL and SDK assemblies marked with %(Trimmable)
are linked at the member level. AndroidLinkMode=Full
sets %(TrimMode)=partial
on all .NET assemblies.
Tip
You should migrate to the new linker settings, because the AndroidLinkMode
setting will eventually be deprecated.
.NET 9 has new settings for the linker:
<TrimMode>Full</TrimMode>
, which performs full trimming.
For more information, see Trimming options.
In .NET for Android projects by default, Debug
builds don't use the linker, and Release
builds set PublishTrimmed=true
and TrimMode=partial
.
Ahead-of-Time compilation
$(RunAOTCompilation)
is the new MSBuild property for enabling Ahead-of-Time (AoT) compilation. This is the same property used for Blazor WASM. The $(AotAssemblies)
property also enables AOT, in order to help with migration from Xamarin.Android projects to .NET for Android projects. However, this property was deprecated in .NET 7.
Release builds default to the following AOT property values:
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<RunAOTCompilation>true</RunAOTCompilation>
<AndroidEnableProfiledAot>true</AndroidEnableProfiledAot>
</PropertyGroup>
This is the behavior when the $(RunAOTCompilation)
and $(AndroidEnableProfiledAot)
properties are unset, and chooses the optimal settings for startup time and app size.
To disable AOT, you need to explicitly set the $(RunAOTCompilation)
and $(AndroidEnableProfiledAot)
properties to false
:
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<RunAOTCompilation>false</RunAOTCompilation>
<AndroidEnableProfiledAot>false</AndroidEnableProfiledAot>
</PropertyGroup>
Supported encodings
If your Xamarin.Android app uses certain international codesets, they have to be specified explicitly in your project file using the Mandroidl18n
MSBuild property, so that the linker can include supporting resources. For more information about this build property, see MAndroidl18n.
However, the Mandroidl18n
MSBuild property isn't supported in .NET for Android apps. Instead, support is provided by the System.TextEncoding.CodePages NuGet package. For more information, see CodePagesEncodingProvider.
.NET CLI
.NET for Android supports using .NET command-line interface (.NET CLI) to create, build, publish, and run Android apps.
dotnet new
dotnet new
can be used to create new .NET for Android projects and items using project templates and item templates that are named following the patterns and naming of existing .NET templates:
Template | Short Name | Language | Tags |
---|---|---|---|
Android Activity template | android-activity | C# | Android |
Android Java Library Binding | android-bindinglib | C# | Android |
Android Layout template | android-layout | C# | Android |
Android Class library | androidlib | C# | Android |
Android Application | android | C# | Android |
The following examples show using dotnet new
to create different types of .NET for Android projects:
dotnet new android --output MyAndroidApp --packageName com.mycompany.myandroidapp
dotnet new androidlib --output MyAndroidLibrary
dotnet new android-bindinglib --output MyJavaBinding
Once .NET for Android projects have been created, item templates can be used to add items to the projects:
dotnet new android-activity --name LoginActivity --namespace MyAndroidApp
dotnet new android-layout --name MyLayout --output Resources/layout
dotnet build & publish
For .NET for Android, dotnet build
produces a runnable app. This means creating an .apk
or .aab
file during the build process, and reordering MSBuild tasks from the .NET SDK so that they run during the build. Therefore, .NET for Android does the following during a build:
- Run
aapt
to generateResource.designer.cs
and potentially emit build errors for issues in@(AndroidResource)
files. - Compile C# code.
- Run the ILLink MSBuild target for linking.
- Generate java stubs, and
AndroidManifest.xml
. - Compile java code via
javac
. - Convert java code to
.dex
via d8/r8. - Create an
.apk
or.aab
and sign it.
dotnet publish
is reserved for publishing an app for Google Play and other distribution mechanisms such as ad-hoc. It also signs the .apk
or .aab
with different keys.
Note
Behavior inside IDEs will differ. The Build
target will not produce an .apk
file if $(BuildingInsideVisualStudio)
is true
. IDEs will call the Install
target for deployment, which will produce the .apk
file. This behavior matches Xamarin.Android.
dotnet run
dotnet run
can be used to launch apps on a device or emulator via the --project
argument:
dotnet run --project HelloAndroid.csproj
Alternatively, you could use the Run
MSBuild target:
dotnet build HelloAndroid.csproj -t:Run