Skip to content

[Xamarin.Android.Build.Tasks] error for Android.Support #8629

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Jan 18, 2024
47 changes: 47 additions & 0 deletions Documentation/guides/messages/xa1039.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
title: Xamarin.Android error XA1039
description: XA1039 error code
ms.date: 1/10/2024
---
# Xamarin.Android error XA1039

## Example messages

```
error XA1039: The Android Support libraries are not supported in .NET 9 and later, please migrate to AndroidX. See https://aka.ms/xamarin/androidx for more details.
```

## Issue

Outdated "Android Support Library" packages are no longer supported in .NET 9:

* `Xamarin.Android.Arch.*`
* `Xamarin.Android.Support.*`

The underlying Java libraries are no longer supported by Google since the final
28.0.0 release. See the [Android Support Library Documentation][support] for
details.

Some example prefixes of the newer, supported AndroidX packages are:

* `Xamarin.AndroidX.*`
* `Xamarin.AndroidX.Arch.*`

For more information about the Android Support libraries or AndroidX, see:

* [Android Support Library Documentation][support]
* [AndroidX Documentation](https://developer.android.com/jetpack/androidx)

[support]: https://developer.android.com/topic/libraries/support-library/packages

## Solution

Remove all NuGet package references to `Xamarin.Android.Support` or
`Xamarin.Android.Arch` in favor of the new AndroidX equivalents.

This also can occur if you are using a NuGet package with a transitive
dependency on the Android support packages. In this case, you will need to
remove the package or contact the package author.

See the [AndroidX migration documentation](https://aka.ms/xamarin/androidx) for
details.
4 changes: 4 additions & 0 deletions src/Xamarin.Android.Build.Tasks/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -1006,4 +1006,8 @@ To use a custom JDK path for a command line build, set the 'JavaSdkDirectory' MS
{0} - The deprecated MSBuild property name
{1} - The numeric version of .NET</comment>
</data>
<data name="XA1039" xml:space="preserve">
<value>The Android Support libraries are not supported in .NET 9 and later, please migrate to AndroidX. See https://aka.ms/xamarin/androidx for more details.</value>
<comment>The following are literal names and should not be translated: Android Support, AndroidX, .NET.</comment>
</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -138,23 +138,17 @@ public void DesignTimeBuild ([Values(false, true)] bool isRelease, [Values (fals
}

[Test]
public void CheckEmbeddedSupportLibraryResources ()
public void CheckEmbeddedAndroidXResources ()
{
var proj = new XamarinAndroidApplicationProject () {
IsRelease = true,
PackageReferences = {
KnownPackages.SupportMediaCompat_27_0_2_1,
KnownPackages.SupportFragment_27_0_2_1,
KnownPackages.SupportCoreUtils_27_0_2_1,
KnownPackages.SupportCoreUI_27_0_2_1,
KnownPackages.SupportCompat_27_0_2_1,
KnownPackages.AndroidSupportV4_27_0_2_1,
KnownPackages.SupportV7AppCompat_27_0_2_1,
KnownPackages.AndroidXAppCompat,
},
};
using (var b = CreateApkBuilder ()) {
Assert.IsTrue (b.Build (proj), "First build should have succeeded.");
var Rdrawable = b.Output.GetIntermediaryPath (Path.Combine ("android", "bin", "classes", "android", "support", "v7", "appcompat", "R$drawable.class"));
var Rdrawable = b.Output.GetIntermediaryPath (Path.Combine ("android", "bin", "classes", "androidx", "appcompat", "R$drawable.class"));
Assert.IsTrue (File.Exists (Rdrawable), $"{Rdrawable} should exist");
}
}
Expand Down Expand Up @@ -410,8 +404,7 @@ protected override void OnClick()
}
}"
});
proj.PackageReferences.Add (KnownPackages.AndroidSupportV4_27_0_2_1);
proj.PackageReferences.Add (KnownPackages.SupportV7AppCompat_27_0_2_1);
proj.PackageReferences.Add (KnownPackages.AndroidXAppCompat);
using (var libb = CreateDllBuilder (Path.Combine (projectPath, lib.ProjectName), cleanupOnDispose: false))
using (var b = CreateApkBuilder (Path.Combine (projectPath, proj.ProjectName), cleanupOnDispose: false)) {
Assert.IsTrue (libb.Build (lib), "Library Build should have succeeded.");
Expand Down Expand Up @@ -831,10 +824,6 @@ public void CheckFilesAreRemoved () {
</resources>",
}
},
PackageReferences = {
KnownPackages.SupportV7AppCompat_27_0_2_1,
KnownPackages.AndroidSupportV4_27_0_2_1,
},
};
using (var builder = CreateApkBuilder ()) {
Assert.IsTrue (builder.Build (proj), "Build should have succeeded");
Expand Down Expand Up @@ -1033,13 +1022,7 @@ public void BuildAppWithManagedResourceParserAndLibraries ()
new BuildItem.ProjectReference (@"..\Lib1\Lib1.csproj", libProj.ProjectName, libProj.ProjectGuid),
},
PackageReferences = {
KnownPackages.SupportMediaCompat_27_0_2_1,
KnownPackages.SupportFragment_27_0_2_1,
KnownPackages.SupportCoreUtils_27_0_2_1,
KnownPackages.SupportCoreUI_27_0_2_1,
KnownPackages.SupportCompat_27_0_2_1,
KnownPackages.AndroidSupportV4_27_0_2_1,
KnownPackages.SupportV7AppCompat_27_0_2_1,
KnownPackages.AndroidXAppCompat,
},
};
appProj.SetProperty ("AndroidUseManagedDesignTimeResourceGenerator", "True");
Expand Down Expand Up @@ -1224,20 +1207,7 @@ public void CustomViewAddResourceId ()
{
var proj = new XamarinAndroidApplicationProject ();
proj.LayoutMain = proj.LayoutMain.Replace ("</LinearLayout>", "<android.support.design.widget.BottomNavigationView android:id=\"@+id/navigation\" /></LinearLayout>");
proj.PackageReferences.Add (KnownPackages.Android_Arch_Core_Common_26_1_0);
proj.PackageReferences.Add (KnownPackages.Android_Arch_Lifecycle_Common_26_1_0);
proj.PackageReferences.Add (KnownPackages.Android_Arch_Lifecycle_Runtime_26_1_0);
proj.PackageReferences.Add (KnownPackages.AndroidSupportV4_27_0_2_1);
proj.PackageReferences.Add (KnownPackages.SupportCompat_27_0_2_1);
proj.PackageReferences.Add (KnownPackages.SupportCoreUI_27_0_2_1);
proj.PackageReferences.Add (KnownPackages.SupportCoreUtils_27_0_2_1);
proj.PackageReferences.Add (KnownPackages.SupportDesign_27_0_2_1);
proj.PackageReferences.Add (KnownPackages.SupportFragment_27_0_2_1);
proj.PackageReferences.Add (KnownPackages.SupportMediaCompat_27_0_2_1);
proj.PackageReferences.Add (KnownPackages.SupportV7AppCompat_27_0_2_1);
proj.PackageReferences.Add (KnownPackages.SupportV7CardView_27_0_2_1);
proj.PackageReferences.Add (KnownPackages.SupportV7MediaRouter_27_0_2_1);
proj.PackageReferences.Add (KnownPackages.SupportV7RecyclerView_27_0_2_1);
proj.PackageReferences.Add (KnownPackages.AndroidXAppCompat);
using (var b = CreateApkBuilder (Path.Combine ("temp", TestName))) {
Assert.IsTrue (b.Build (proj), "first build should have succeeded");

Expand All @@ -1257,7 +1227,7 @@ public void CustomViewAddResourceId ()
var r_java = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, "android", "src", proj.PackageNameJavaIntermediatePath, "R.java");
FileAssert.Exists (r_java);
var r_java_contents = File.ReadAllLines (r_java);
Assert.IsTrue (StringAssertEx.ContainsText (r_java_contents, textView1), $"android/support/compat/R.java should contain `{textView1}`!");
Assert.IsTrue (StringAssertEx.ContainsText (r_java_contents, textView1), $"{r_java} should contain `{textView1}`!");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,6 @@ public void BuildAarBindigLibraryWithNuGetPackageOfJar (string classParser)
var proj = new XamarinAndroidBindingProject () {
IsRelease = true,
};
proj.PackageReferences.Add (KnownPackages.AndroidSupportV4_27_0_2_1);
proj.Jars.Add (new AndroidItem.LibraryProjectZip ("Jars\\android-crop-1.0.1.aar") {
WebContent = "https://repo1.maven.org/maven2/com/soundcloud/android/android-crop/1.0.1/android-crop-1.0.1.aar"
});
Expand All @@ -187,13 +186,12 @@ public void BuildAarBindigLibraryWithNuGetPackageOfJar (string classParser)
[Test]
[TestCaseSource (nameof (ClassParseOptions))]
[NonParallelizable]
public void BuildLibraryZipBindigLibraryWithAarOfJar (string classParser)
public void BuildLibraryZipBindingLibraryWithAarOfJar (string classParser)
{
var proj = new XamarinAndroidBindingProject () {
IsRelease = true,
};
proj.AndroidClassParser = classParser;
proj.PackageReferences.Add (KnownPackages.AndroidSupportV4_27_0_2_1);
proj.Jars.Add (new AndroidItem.LibraryProjectZip ("Jars\\aFileChooserBinaries.zip") {
WebContentFileNameFromAzure = "aFileChooserBinaries.zip"
});
Expand All @@ -202,41 +200,6 @@ public void BuildLibraryZipBindigLibraryWithAarOfJar (string classParser)
<attr path=""/api/package[@name='com.ipaulpro.afilechooser']/class[@name='FileListAdapter']/method[@name='getItem' and count(parameter)=1 and parameter[1][@type='int']]"" name=""managedReturn"">Java.Lang.Object</attr>
<attr path=""/api/package[@name='com.ipaulpro.afilechooser']/class[@name='FileLoader']/method[@name='loadInBackground' and count(parameter)=0]"" name=""managedName"">LoadInBackgroundImpl</attr>
</metadata>";
proj.Sources.Add (new BuildItem (BuildActions.Compile, "Fixup.cs") {
TextContent = () => @"using System;
using System.Collections.Generic;
using Android.App;
using Android.Runtime;

namespace Com.Ipaulpro.Afilechooser {
[Activity (Name = ""com.ipaulpro.afilechooser.FileChooserActivity"",
Icon = ""@drawable/ic_chooser"",
Exported = true)]
[IntentFilter (new string [] {""android.intent.action.GET_CONTENT""},
Categories = new string [] {
""android.intent.category.DEFAULT"",
//""android.intent.category.OPENABLE""
},
DataMimeType = ""*/*"")]
public partial class FileChooserActivity
{
}

public partial class FileListFragment : global::Android.Support.V4.App.ListFragment, global::Android.Support.V4.App.LoaderManager.ILoaderCallbacks {

public void OnLoadFinished (global::Android.Support.V4.Content.Loader p0, Java.Lang.Object p1)
{
OnLoadFinished (p0, (IList<Java.IO.File>) new JavaList<Java.IO.File> (p1.Handle, JniHandleOwnership.DoNotTransfer));
}
}
public partial class FileLoader : Android.Support.V4.Content.AsyncTaskLoader {
public override Java.Lang.Object LoadInBackground ()
{
return (Java.Lang.Object) LoadInBackgroundImpl ();
}
}
}"
});
using (var b = CreateDllBuilder ()) {
Assert.IsTrue (b.Build (proj), "Build should have succeeded.");
}
Expand Down Expand Up @@ -467,7 +430,6 @@ public void RemoveEventHandlerResolution ()
<attr path=""/api/package[@name='com.actionbarsherlock.view']"" name=""managedName"">Xamarin.ActionbarSherlockBinding.Views</attr>
</metadata>",
};
binding.PackageReferences.Add (KnownPackages.AndroidSupportV4_27_0_2_1);
using (var bindingBuilder = CreateDllBuilder (Path.Combine ("temp", "RemoveEventHandlerResolution", "Binding"))) {
Assert.IsTrue (bindingBuilder.Build (binding), "binding build should have succeeded");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,17 +243,9 @@ public void CheckAssemblyCounts (bool isRelease, bool aot)
EmbedAssembliesIntoApk = true,
AotAssemblies = aot,
};
proj.PackageReferences.Add (KnownPackages.AndroidXMigration);
proj.PackageReferences.Add (KnownPackages.AndroidXAppCompat);
proj.PackageReferences.Add (KnownPackages.AndroidXAppCompatResources);
proj.PackageReferences.Add (KnownPackages.AndroidXBrowser);
proj.PackageReferences.Add (KnownPackages.AndroidXMediaRouter);
proj.PackageReferences.Add (KnownPackages.AndroidXLegacySupportV4);
proj.PackageReferences.Add (KnownPackages.AndroidXLifecycleLiveData);
proj.PackageReferences.Add (KnownPackages.XamarinGoogleAndroidMaterial);

var abis = new [] { "armeabi-v7a", "x86" };
proj.SetAndroidSupportedAbis (abis);
proj.SetRuntimeIdentifiers (abis);
proj.SetProperty (proj.ActiveConfigurationProperties, "AndroidUseAssemblyStore", "True");

using (var b = CreateApkBuilder ()) {
Expand Down Expand Up @@ -292,10 +284,6 @@ public void SmokeTestBuildWithSpecialCharacters ([Values (false, true)] bool for
proj.IsRelease = true;
proj.AotAssemblies = aot;

if (forms) {
proj.PackageReferences.Clear ();
proj.PackageReferences.Add (KnownPackages.XamarinForms_4_7_0_1142);
}
using (var builder = CreateApkBuilder (Path.Combine (rootPath, proj.ProjectName))){
Assert.IsTrue (builder.Build (proj), "Build should have succeeded.");
}
Expand Down Expand Up @@ -450,19 +438,14 @@ public void ApplicationIdPlaceholder ()
public void ExtraAaptManifest ()
Copy link
Member

@jonpryor jonpryor Jan 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this test removed? It doesn't appear to (directly?) use the Support libraries; presumably it's because it starts with Xamarin.Android. Is there not a newer Crashytics? It looks like there's a Xamarin.Firebase.Crashlytics package which exists…

This test is also weird, in that it's the only test that uses Crashlytics.HandleManagedExceptions()

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was able to put it back, using:

  • Xamarin.Firebase.Crashlytics NuGet
  • Firebase.Crashlytics.FirebaseCrashlytics.Instance.SendUnsentReports()
  • Look for firebaseinitprovider in the AndroidManifest.xml

{
var proj = new XamarinAndroidApplicationProject ();
proj.MainActivity = proj.DefaultMainActivity.Replace ("base.OnCreate (bundle);", "base.OnCreate (bundle);\nCrashlytics.Crashlytics.HandleManagedExceptions();");
proj.PackageReferences.Add (KnownPackages.Xamarin_Android_Crashlytics);
proj.PackageReferences.Add (KnownPackages.Xamarin_Android_Fabric);
proj.MainActivity = proj.DefaultMainActivity.Replace ("base.OnCreate (bundle);", "base.OnCreate (bundle);\nFirebase.Crashlytics.FirebaseCrashlytics.Instance.SendUnsentReports();");
proj.PackageReferences.Add (new Package { Id = "Xamarin.Firebase.Crashlytics", Version = "118.5.1.1" });
proj.PackageReferences.Add (KnownPackages.Xamarin_Build_Download);
using (var builder = CreateApkBuilder (Path.Combine ("temp", TestName))) {
builder.Target = "Restore";
Assert.IsTrue (builder.Build (proj), "Restore should have succeeded.");
builder.Target = "Build";
Assert.IsTrue (builder.Build (proj), "Build should have succeeded.");
var manifest = File.ReadAllText (Path.Combine (Root, builder.ProjectDirectory, "obj", "Debug", "android", "AndroidManifest.xml"));
Assert.IsTrue (manifest.Contains ($"android:authorities=\"{proj.PackageName}.crashlyticsinitprovider\""), "placeholder not replaced");
Assert.IsFalse (manifest.Contains ("dollar_openBracket_applicationId_closeBracket"), "`aapt/AndroidManifest.xml` not ignored");
}
using var builder = CreateApkBuilder ();
Assert.IsTrue (builder.Build (proj), "Build should have succeeded.");
var manifest = File.ReadAllText (Path.Combine (Root, builder.ProjectDirectory, "obj", "Debug", "android", "AndroidManifest.xml"));
Assert.IsTrue (manifest.Contains ($"android:authorities=\"{proj.PackageName}.firebaseinitprovider\""), "placeholder not replaced");
Assert.IsFalse (manifest.Contains ("dollar_openBracket_applicationId_closeBracket"), "`aapt/AndroidManifest.xml` not ignored");
}

[Test]
Expand Down Expand Up @@ -714,7 +697,10 @@ public void BuildAfterUpgradingNuget ()
var proj = new XamarinAndroidApplicationProject ();
proj.MainActivity = proj.DefaultMainActivity.Replace ("public class MainActivity : Activity", "public class MainActivity : AndroidX.AppCompat.App.AppCompatActivity");

proj.PackageReferences.Add (KnownPackages.AndroidXAppCompat);
proj.PackageReferences.Add (new Package {
Id = "Xamarin.AndroidX.AppCompat",
Version = "1.6.1.5",
});

using (var b = CreateApkBuilder (Path.Combine ("temp", TestContext.CurrentContext.Test.Name))) {
//[TearDown] will still delete if test outcome successful, I need logs if assertions fail but build passes
Expand All @@ -732,8 +718,8 @@ public void BuildAfterUpgradingNuget ()
FileAssert.Exists (build_props, "build.props should exist after first build.");

proj.PackageReferences.Clear ();
//NOTE: we can get all the other dependencies transitively, yay!
proj.PackageReferences.Add (KnownPackages.AndroidXAppCompat_1_6_0_1);
//NOTE: this should be newer than specified above
proj.PackageReferences.Add (KnownPackages.AndroidXAppCompat);
b.Save (proj, doNotCleanupOnUpdate: true);
Assert.IsTrue (b.Build (proj), "second build should have succeeded.");
Assert.IsFalse (b.Output.IsTargetSkipped ("_CleanIntermediateIfNeeded"), "`_CleanIntermediateIfNeeded` should have run for the second build!");
Expand Down Expand Up @@ -1165,6 +1151,7 @@ public MyWorker (Context c, WorkerParameters p) : base (c, p) { }
"
});
proj.PackageReferences.Add (KnownPackages.AndroidXWorkRuntime);
proj.PackageReferences.Add (KnownPackages.AndroidXLifecycleLiveData);
using (var b = CreateApkBuilder (Path.Combine ("temp", TestName))) {
Assert.IsTrue (b.Build (proj), "Build should have succeeded.");
}
Expand Down Expand Up @@ -1436,12 +1423,7 @@ public void CheckLintErrorsAndWarnings ()
{
string disabledIssues = "StaticFieldLeak,ObsoleteSdkInt,AllowBackup,ExportedReceiver,RedundantLabel";

var proj = new XamarinAndroidApplicationProject () {
PackageReferences = {
KnownPackages.AndroidSupportV4_27_0_2_1,
KnownPackages.SupportConstraintLayout_1_0_2_2,
},
};
var proj = new XamarinAndroidApplicationProject ();
proj.SetProperty ("AndroidLintEnabled", true.ToString ());
proj.SetProperty ("AndroidLintDisabledIssues", disabledIssues);
proj.SetProperty ("AndroidLintEnabledIssues", "");
Expand All @@ -1458,14 +1440,12 @@ public class MainActivity : Activity
TextContent = () => {
return @"<?xml version=""1.0"" encoding=""utf-8""?>
<ConstraintLayout xmlns:android=""http://schemas.android.com/apk/res/android""
xmlns:app=""http://schemas.android.com/apk/res-auto""
android:orientation=""vertical""
android:layout_width=""fill_parent""
android:layout_height=""fill_parent"">
<TextView android:id=""@+id/foo""
android:layout_width=""150dp""
android:layout_height=""wrap_content""
app:layout_constraintTop_toTopOf=""parent""
/>
</ConstraintLayout>";
}
Expand Down Expand Up @@ -1621,25 +1601,18 @@ public void DuplicateValuesInResourceCaseMap ()
[Test]
public void CheckLintResourceFileReferencesAreFixed ()
{
var proj = new XamarinAndroidApplicationProject () {
PackageReferences = {
KnownPackages.AndroidSupportV4_27_0_2_1,
KnownPackages.SupportConstraintLayout_1_0_2_2,
},
};
var proj = new XamarinAndroidApplicationProject ();
proj.SetProperty ("AndroidLintEnabled", true.ToString ());
proj.AndroidResources.Add (new AndroidItem.AndroidResource ("Resources\\layout\\test.axml") {
TextContent = () => {
return @"<?xml version=""1.0"" encoding=""utf-8""?>
<ConstraintLayout xmlns:android=""http://schemas.android.com/apk/res/android""
xmlns:app=""http://schemas.android.com/apk/res-auto""
android:orientation=""vertical""
android:layout_width=""fill_parent""
android:layout_height=""fill_parent"">
<TextView android:id=""@+id/foo""
android:layout_width=""150dp""
android:layout_height=""wrap_content""
app:layout_constraintTop_toTopOf=""parent""
/>
<EditText
android:id=""@+id/phone""
Expand Down
Loading