Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Target net9.0-android in MAUI: Is It Good Practice?

Is targeting net9.0-android for MAUI projects the right move? Learn how to configure TFM correctly for Android-only builds in CI/CD pipelines.
Split-screen image showing a successful Android build on one side and a failed .NET MAUI build with net9.0-android error on the other, illustrating targeting challenges. Split-screen image showing a successful Android build on one side and a failed .NET MAUI build with net9.0-android error on the other, illustrating targeting challenges.
  • ⚙️ Using net9.0-android greatly reduces build time. It does this by focusing only on Android-specific targets.
  • 🚧 Missing the maui-android workload is a common cause of build failures during Android-only targeting.
  • 📦 Using <TargetFrameworks> to build for many platforms lets you be flexible later. But, it makes build pipelines more complex.
  • 🛠 Pinning your SDK version in global.json stops unexpected SDK version changes.
  • 🔄 Conditional compilation helps you make things work best. And then, it also lets you keep a structure that works for many platforms.

Why TFM Choice Matters in MAUI Projects

Target Framework Monikers (TFMs) are an important part of .NET MAUI project setup. This is true especially if you want to make builds faster for a platform like Android. More teams are starting to use MAUI for mobile apps. Knowing when and how to use platform-specific TFMs, like net9.0-android, saves time and problems in CI/CD pipelines. This article explains when to use net9.0-android. It also shows how it changes builds and gives good ways to avoid common problems.

Understanding .NET Target Framework Monikers (TFMs)

A TFM, or Target Framework Moniker, shows what framework version and platform your app is built for. In .NET, this lets the compiler and build system know which APIs, SDKs, and runtime rules to use.

In traditional .NET, a TFM like net6.0 or net9.0 works across many platforms. It does not tie the app to one operating system. But, MAUI (Multi-platform App UI) is a framework for making apps that work on Android, iOS, Windows, and macOS. So, it can use TFMs just for one platform, such as:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

  • net9.0-android
  • net9.0-ios
  • net9.0-maccatalyst
  • net9.0-windows10.0.19041.0

These monikers for specific platforms let developers choose only one platform.

Multi-targeting is usually done with <TargetFrameworks> in the .csproj file. It lets you build shared code for many TFMs, one after another. For example:

<TargetFrameworks>net9.0-android;net9.0-ios</TargetFrameworks>

But, if your app needs to be for only one platform — if you need faster development, lower costs, or certain business rules — then using a single TFM like net9.0-android can be the best choice.

What Is net9.0-android?

The net9.0-android TFM is the name for just that platform. It tells the compiler to build only for Android when working on a MAUI project. This is a newer version of older Xamarin names like monoandroid10.0.

By clearly putting net9.0-android in your project file, you are telling the build process to:

  • Include only Android parts.
  • Ignore iOS, macOS, and Windows work.
  • Get connections and references only for the Android SDK.
  • Greatly cut down on what needs to be built and how many resources are used.

What is good about net9.0-android:

  • Faster build times: MAUI does not need to build for platforms it does not need.
  • 📦 Fewer dependencies: No outside platform libraries load.
  • 🧱 Simpler CI/CD pipelines: Only focusing on Android deployment means less work.
  • 🧪 Good for MVPs and testing: You can build Android-only apps fast. This happens without needing support for more platforms.

The Reference Assemblies Error Explained

A common and annoying problem when using platform-specific TFMs like net9.0-android is the “reference assemblies” error:

"The reference assemblies for .NETFramework,Version=v0.0 were not found"

This error usually happens because the .NET SDK or needed workload is not installed on the machine. This often happens in new development setups or Docker containers. In these, you have to install workloads yourself.

Why This Happens

Platform-specific TFMs like net9.0-android need workload packs to give them code connections (reference assemblies) to Android SDKs. If you do not install those workloads, the compiler cannot find the types or info it needs for Android builds.

How to fix it

  1. Make sure the needed workload is installed:
dotnet workload list
dotnet workload install maui-android
  1. If you do not know which workloads are missing, this command checks for them. It then installs any missing ones that your project needs:
dotnet workload restore
  1. Check SDK versions match. Use a .NET 9.0 SDK version that works with your MAUI version.

If you use Visual Studio, the installer or project templates do many of these steps automatically. But, if you work in command-line tools like GitHub Actions or Docker, you must install workloads yourself as part of your process.

Best Use Cases for net9.0-android

MAUI is good for making apps for many platforms. But, targeting only Android with net9.0-android can make your work faster and simpler in some cases:

1. Android-Only MVPs or Pilots

If you are building a basic product for Android users, there is not much reason to add the work and time needed to build for other platforms.

2. Enterprise Tooling

Businesses that use Android devices (like tough tablets or barcode scanners) often order apps that do not need to work on other devices.

3. Region-Specific Apps

In markets where Android devices are most common (like some parts of Asia or South America), you might need only Android versions of your app.

4. Simplified Testing and Validation

QA teams might like Android-only builds for automated tests. This is true especially in CI, where Android emulators work better than iOS simulators.

5. CI/CD Efficiency

Pipelines that only handle Android parts (APKs or AABs) make managing tasks simpler. They also lower image size, use less cache, and cut down total build times.

Potential Drawbacks of Android-Only Targeting

Before rushing into net9.0-android, think about these problems and what they might cost in the long run:

🔁 Refactor Overhead

If your project starts as Android-only but later grows to include iOS or Windows, you will need to update TFMs. You will also install new workloads and possibly change any Android-only code not using #if statements.

❌ Library Support Limitations

Some NuGet packages for many platforms might not work well with TFMs made for one platform. They might need general targets like net9.0.

🔍 Debugging Is Harder

Platform-specific TFMs give very specific error messages. This makes it harder to fix problems when something connects to outside parts.

📦 Vendor Lock-In

Separate Android workflows may stop good code sharing across projects or teams using other platforms.

Our advice? Think about how long the project will last. If you might release on iOS five years from now, use multi-targeting from the start.

How to Configure net9.0-android Correctly

To set up a MAUI project to use net9.0-android correctly means setting the right TargetFramework. And then, you need to make sure you install the needed workloads.

1. Update Your .csproj File

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net9.0-android</TargetFramework>
    <OutputType>Exe</OutputType>
    <UseMaui>true</UseMaui>
  </PropertyGroup>
</Project>

You can also do:

<TargetFrameworks>net9.0-android;net9.0-ios</TargetFrameworks>

You can use this if you might add iOS later.

2. Install Workloads

From the CLI:

dotnet workload install maui-android

Or validate current workloads:

dotnet workload list

3. Make sure reference assemblies are there

Install all needed runtime packs. In CI or Docker, setup scripts that run by themselves must have:

dotnet workload install maui-android
dotnet workload restore

Managing Dependencies and Reference Assemblies

How well each TFM build works depends on managing workloads correctly. For net9.0-android, reference assemblies include connections to Android libraries like android.content.Context. They also include controls shown on the platform and ways to use hardware.

Common tooling:

  • dotnet workload list: View installed workloads.
  • dotnet workload install maui-android: Add platform workload.
  • dotnet workload restore: Restore workloads defined in your project.

Visual Studio usually installs workloads without you seeing it. But command-line tools (like CI systems) need you to set them up yourself.

CI/CD Pipeline Optimization for Android-Only Builds

To best control build time and costs in CI providers like GitHub Actions, GitLab, or Azure DevOps, automate and make the Android-only pipeline simpler.

🔩 Use a Lightweight Dockerfile

Only install the SDK and workloads you need. A sample Docker step could look like:

FROM mcr.microsoft.com/dotnet/sdk:9.0-preview
RUN dotnet workload install maui-android

💾 Cache .nuget and Intermediate Outputs

Build caching makes CI runs much faster. Tools like GitHub Actions cache or Azure Pipeline's RestoreCache task can keep dependencies for many builds.

📐 Pin SDK with global.json

Stop unexpected SDK version changes. And then, make sure builds work the same on your computer and in CI:

{
  "sdk": {
    "version": "9.0.100-preview.6"
  }
}

Future-Proofing With SDK Rollforwards

SDK roll-forward means dotnet tries to use a newer SDK version by itself to build projects meant for older versions. This might seem useful, but it can stop builds from working.

🛡 Advice:

  • Always pin SDK: Use global.json.
  • Install workloads that match exactly: The SDK and maui-android workload versions must match.
  • Check often: Run dotnet workload update monthly for new versions.

When Not to Use net9.0-android

Do not target only Android with net9.0-android when:

  • Your app will later work on other platforms.
  • You are making a library or shared service that others will use.
  • Your tests need to work on many platforms.
  • You are making an app for the public.

It is better to start with multi-TFM and conditional logic.

Multi-TFM Targeting with Platform Conditions

When multi-targeting, structure your .csproj as:

<TargetFrameworks>net9.0-android;net9.0-ios;net9.0-windows10.0.19041.0</TargetFrameworks>

Use compiler guards for platform-specific code:

#if ANDROID
   // Only runs on Android builds
#endif

You can also put platform-specific package setup inside MSBuild conditions:

<ItemGroup Condition="'$(TargetFramework)' == 'net9.0-android'">
  <PackageReference Include="Xamarin.Google.Android.Material" Version="1.4.0.4" />
</ItemGroup>

How to avoid mistakes with net9.0-android

  • Missing workloads: Always run dotnet workload restore before building.
  • Thinking all NuGet packages will work: Not all libraries work with TFMs only for Android. Read the docs.
  • Mixing up platform names: Do not use old names like monoandroid. Use only net9.0-android.
  • CI not matching: Make SDK and workload versions the same in both dev and build setups.

So, Is Targeting net9.0-android Good Practice?

Yes, but only in the right situations. Building for one platform is fast and simple when you only need Android.

But, if a project might grow to many platforms, you should keep a multi-targeting structure from the start. This is true even if you only focus on Android at first. Multi-TFM projects might take a little longer to build. But, they give you flexibility and work with newer versions. This is often needed for products that change over time.

Quick Checklist for Android-Only MAUI Builds

  • ✅ Install .NET 9.0 SDK
  • ✅ Check if maui-android workload is installed via dotnet workload list
  • ✅ Use <TargetFramework>net9.0-android</TargetFramework> in .csproj
  • ✅ Set up global.json to hold the SDK version.
  • ✅ Automate workload installs in CI scripts.
  • ✅ Check NuGet packages work with Android-only targets.
  • ✅ Do not use old platform names (monoandroid).
  • ✅ Check reference assemblies are ready before building.

Citations

Microsoft. (n.d.). Target frameworks. Learn.microsoft.com. https://learn.microsoft.com/en-us/dotnet/standard/frameworks

Microsoft. (2023). SDK Workloads in .NET MAUI. Learn.microsoft.com. https://learn.microsoft.com/en-us/dotnet/maui/workloads/workload-manifest

Microsoft. (2023). dotnet workload install documentation. Learn.microsoft.com. https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-workload-install

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading