diff --git a/Documentation/guides/messages/README.md b/Documentation/guides/messages/README.md
index af06e1bd243..6a4feb91b2e 100644
--- a/Documentation/guides/messages/README.md
+++ b/Documentation/guides/messages/README.md
@@ -222,6 +222,10 @@ Exceptions that have not been gracefully handled yet. Ideally these will be fix
These take the form of `XACCC7NNN`, where `CCC` is a 3 character code denoting the MSBuild Task that is throwing the exception,
and `NNN` is a 3 digit number indicating the type of the unhandled `Exception`.
+## XA8xxx: Linker Step Errors
+
++ [XA8000/IL8000](xa8000.md): Could not find Android Resource '@anim/enterfromright'. Please update @(AndroidResource) to add the missing resource.
+
**Tasks:**
* `A2C` - `Aapt2Compile`
* `A2L` - `Aapt2Link`
diff --git a/Documentation/guides/messages/xa8000.md b/Documentation/guides/messages/xa8000.md
new file mode 100644
index 00000000000..5b09ba1251f
--- /dev/null
+++ b/Documentation/guides/messages/xa8000.md
@@ -0,0 +1,21 @@
+---
+title: Xamarin.Android warning XA8000/IL8000
+description: XA8000/IL8000 error code
+ms.date: 06/01/2023
+---
+# Xamarin.Android error XA8000/IL8000
+
+## Issue
+
+```
+Could not find Android Resource '@anim/enterfromright'. Please update @(AndroidResource) to add the missing resource.
+```
+
+## Solution
+
+When trying to upgrade older nuget package references to use the
+more recent Resource Designer Assembly, the system might encounter
+fields which cannot be upgraded because the resource is missing
+from either the dependency or the app.
+
+To fix this issue the missing `AndroidResource` needs to be added to the application. Or the Nuget should be upgraded to use .net 8 or later.
\ No newline at end of file
diff --git a/build-tools/scripts/UpdateApkSizeReference.sh b/build-tools/scripts/UpdateApkSizeReference.sh
index 55bc755de94..6bfd1f05278 100755
--- a/build-tools/scripts/UpdateApkSizeReference.sh
+++ b/build-tools/scripts/UpdateApkSizeReference.sh
@@ -1,4 +1,3 @@
#!/bin/bash
-./build-tools/scripts/nunit3-console bin/TestRelease/net472/Xamarin.Android.Build.Tests.dll --test=Xamarin.Android.Build.Tests.BuildTest2.BuildReleaseArm64
./dotnet-local.sh test bin/TestRelease/net7.0/Xamarin.Android.Build.Tests.dll --filter=Name~BuildReleaseArm64
cp bin/TestRelease/BuildReleaseArm64*.apkdesc src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/
\ No newline at end of file
diff --git a/src/Microsoft.Android.Sdk.ILLink/Properties/Resources.Designer.cs b/src/Microsoft.Android.Sdk.ILLink/Properties/Resources.Designer.cs
index 6a5d84b56eb..e9883a88c78 100644
--- a/src/Microsoft.Android.Sdk.ILLink/Properties/Resources.Designer.cs
+++ b/src/Microsoft.Android.Sdk.ILLink/Properties/Resources.Designer.cs
@@ -10,8 +10,8 @@
namespace Microsoft.Android.Sdk.ILLink.Properties {
using System;
-
-
+
+
///
/// A strongly-typed resource class, for looking up localized strings, etc.
///
@@ -23,15 +23,15 @@ namespace Microsoft.Android.Sdk.ILLink.Properties {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class Resources {
-
+
private static global::System.Resources.ResourceManager resourceMan;
-
+
private static global::System.Globalization.CultureInfo resourceCulture;
-
+
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
-
+
///
/// Returns the cached ResourceManager instance used by this class.
///
@@ -45,7 +45,7 @@ internal Resources() {
return resourceMan;
}
}
-
+
///
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
@@ -59,7 +59,7 @@ internal Resources() {
resourceCulture = value;
}
}
-
+
///
/// Looks up a localized string similar to Use of AppDomain.CreateDomain() detected in assembly: {0}. .NET 6 and higher will only support a single AppDomain, so this API will no longer be available in Xamarin.Android once .NET 6 is released..
///
@@ -68,5 +68,14 @@ public static string XA2000 {
return ResourceManager.GetString("XA2000", resourceCulture);
}
}
+
+ ///
+ /// Looks up a localized string similar to Could not find an 'AndroidResource' for 'anim'.
+ ///
+ public static string XA8000 {
+ get {
+ return ResourceManager.GetString("XA8000", resourceCulture);
+ }
+ }
}
}
diff --git a/src/Microsoft.Android.Sdk.ILLink/Properties/Resources.resx b/src/Microsoft.Android.Sdk.ILLink/Properties/Resources.resx
index 6d76ecca22f..0e3f8e775d4 100644
--- a/src/Microsoft.Android.Sdk.ILLink/Properties/Resources.resx
+++ b/src/Microsoft.Android.Sdk.ILLink/Properties/Resources.resx
@@ -122,4 +122,10 @@
The following are literal names and should not be translated: AppDomain.CreateDomain(), AppDomain
{0} - The name of the assembly
+
+ Could not find Android Resource '{0}'. Please update @(AndroidResource) to add the missing resource.
+
+{0} - An Android Resource Identifier.
+
+
\ No newline at end of file
diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixLegacyResourceDesignerStep.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixLegacyResourceDesignerStep.cs
index d5ca2e4c65c..2f8569f515a 100644
--- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixLegacyResourceDesignerStep.cs
+++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixLegacyResourceDesignerStep.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.Linq;
using Mono.Cecil;
@@ -13,6 +14,9 @@
using Mono.Tuner;
#if ILLINK
using Microsoft.Android.Sdk.ILLink;
+using Resources = Microsoft.Android.Sdk.ILLink.Properties.Resources;
+#else // !ILLINK
+using Resources = Xamarin.Android.Tasks.Properties.Resources;
#endif // ILLINK
namespace MonoDroid.Tuner
@@ -120,6 +124,17 @@ Dictionary BuildResourceDesignerPropertyLookup (TypeDe
return output;
}
+ string GetNativeTypeNameFromManagedTypeName (string name)
+ {
+ switch (name) {
+ case "Animation": return "anim";
+ case "Attribute": return "attr";
+ case "Boolean": return "bool";
+ case "Dimension": return "dimen";
+ default: return name.ToLower ();
+ }
+ }
+
protected override void FixBody (MethodBody body, TypeDefinition designer)
{
// replace
@@ -144,6 +159,14 @@ protected override void FixBody (MethodBody body, TypeDefinition designer)
instructions.Add (i, newIn);
} else {
LogMessage ($"DEBUG! Failed to find {key}!");
+ // The 'key' in this case will be something like Layout::Toolbar.
+ // We want format this into @layout/Toolbar so its easier to understand
+ // for the user.
+ var index = key.IndexOf ("::");
+ var typeName = GetNativeTypeNameFromManagedTypeName (key.Substring (0, index));
+ var identifier = key.Substring (index + 2);
+ var msg = string.Format (CultureInfo.CurrentCulture, Resources.XA8000, $"@{typeName}/{identifier}");
+ LogError (8000, msg);
}
}
}
diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/LinkDesignerBase.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/LinkDesignerBase.cs
index 2c30e4ba228..d8c65f1b573 100644
--- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/LinkDesignerBase.cs
+++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/LinkDesignerBase.cs
@@ -21,6 +21,15 @@ public virtual void LogMessage (string message)
Context.LogMessage (message);
}
+ public virtual void LogError (int code, string error)
+ {
+#if ILLINK
+ Context.LogMessage (MessageContainer.CreateCustomErrorMessage (error, code, origin: new MessageOrigin ()));
+#else // !ILLINK
+ Console.Error.WriteLine ($"error XA{code}: {error}");
+#endif // !ILLINK
+ }
+
public virtual AssemblyDefinition Resolve (AssemblyNameReference name)
{
return Context.Resolve (name);
diff --git a/src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs b/src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs
index a5f6eb2399f..7fe1bf1c1ae 100644
--- a/src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs
+++ b/src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs
@@ -116,6 +116,15 @@ public static string XA_Directory_Is_From {
}
}
+ ///
+ /// Looks up a localized string similar to Could not find an 'AndroidResource' for 'anim'.
+ ///
+ public static string XA8000 {
+ get {
+ return ResourceManager.GetString("XA8000", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to
/// This code was generated by a tool.
diff --git a/src/Xamarin.Android.Build.Tasks/Properties/Resources.resx b/src/Xamarin.Android.Build.Tasks/Properties/Resources.resx
index 768256ab6e6..dfb964b4851 100644
--- a/src/Xamarin.Android.Build.Tasks/Properties/Resources.resx
+++ b/src/Xamarin.Android.Build.Tasks/Properties/Resources.resx
@@ -933,4 +933,10 @@ To use a custom JDK path for a command line build, set the 'JavaSdkDirectory' MS
{1} - A Filename.
+
+ Could not find Android Resource '{0}'. Please update @(AndroidResource) to add the missing resource.
+
+{0} - An Android Resource Identifier.
+
+
diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/LinkAssembliesNoShrink.cs b/src/Xamarin.Android.Build.Tasks/Tasks/LinkAssembliesNoShrink.cs
index 78804fcf315..2d42039fce2 100644
--- a/src/Xamarin.Android.Build.Tasks/Tasks/LinkAssembliesNoShrink.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tasks/LinkAssembliesNoShrink.cs
@@ -142,6 +142,11 @@ public override void LogMessage (string message)
logger.LogDebugMessage ("{0}", message);
}
+ public override void LogError (int code, string message)
+ {
+ logger.LogCodedError ($"XA{code}", message);
+ }
+
public override AssemblyDefinition Resolve (AssemblyNameReference name)
{
return resolver.Resolve (name);
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/KnownPackages.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/KnownPackages.cs
index 007ff8d4172..c4dca5c2b42 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/KnownPackages.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/KnownPackages.cs
@@ -593,6 +593,14 @@ public static class KnownPackages
Id = "Mono.AotProfiler.Android",
Version = "7.0.0-preview1",
};
+ public static Package SkiaSharp = new Package () {
+ Id = "SkiaSharp",
+ Version = "2.88.3",
+ };
+ public static Package SkiaSharp_Views = new Package () {
+ Id = "SkiaSharp.Views",
+ Version = "2.88.3",
+ };
}
}
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc
index dc72d5e2ad3..74cdceacd9e 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc
@@ -8,58 +8,58 @@
"Size": 1024
},
"assemblies/Java.Interop.dll": {
- "Size": 58913
+ "Size": 58703
},
"assemblies/Mono.Android.dll": {
- "Size": 87163
+ "Size": 86588
},
"assemblies/Mono.Android.Runtime.dll": {
- "Size": 5895
+ "Size": 5798
},
"assemblies/rc.bin": {
- "Size": 1182
+ "Size": 1235
},
"assemblies/System.Console.dll": {
- "Size": 6438
+ "Size": 6442
},
"assemblies/System.Linq.dll": {
- "Size": 9122
+ "Size": 9123
},
"assemblies/System.Private.CoreLib.dll": {
- "Size": 516811
+ "Size": 536436
},
"assemblies/System.Runtime.dll": {
- "Size": 2620
+ "Size": 2623
},
"assemblies/System.Runtime.InteropServices.dll": {
- "Size": 3753
+ "Size": 3752
},
"assemblies/UnnamedProject.dll": {
- "Size": 3219
+ "Size": 3349
},
"classes.dex": {
- "Size": 19020
+ "Size": 19748
},
"lib/arm64-v8a/libmono-component-marshal-ilgen.so": {
"Size": 93552
},
"lib/arm64-v8a/libmonodroid.so": {
- "Size": 379320
+ "Size": 380832
},
"lib/arm64-v8a/libmonosgen-2.0.so": {
- "Size": 3090760
+ "Size": 3160360
},
"lib/arm64-v8a/libSystem.IO.Compression.Native.so": {
- "Size": 723840
+ "Size": 723560
},
"lib/arm64-v8a/libSystem.Native.so": {
- "Size": 94328
+ "Size": 94392
},
"lib/arm64-v8a/libSystem.Security.Cryptography.Native.Android.so": {
- "Size": 155056
+ "Size": 154904
},
"lib/arm64-v8a/libxamarin-app.so": {
- "Size": 16720
+ "Size": 16624
},
"META-INF/BNDLTOOL.RSA": {
"Size": 1213
@@ -95,5 +95,5 @@
"Size": 1904
}
},
- "PackageSize": 2632010
+ "PackageSize": 2685258
}
\ No newline at end of file
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsDotNet.apkdesc b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsDotNet.apkdesc
index 415590216dc..26e5420ad28 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsDotNet.apkdesc
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsDotNet.apkdesc
@@ -5,136 +5,136 @@
"Size": 3568
},
"assemblies/_Microsoft.Android.Resource.Designer.dll": {
- "Size": 1940
+ "Size": 2102
},
"assemblies/FormsViewGroup.dll": {
"Size": 7313
},
"assemblies/Java.Interop.dll": {
- "Size": 66903
+ "Size": 66576
},
"assemblies/Mono.Android.dll": {
- "Size": 468307
+ "Size": 446254
},
"assemblies/Mono.Android.Runtime.dll": {
- "Size": 5894
+ "Size": 5798
},
"assemblies/mscorlib.dll": {
"Size": 3860
},
"assemblies/netstandard.dll": {
- "Size": 5579
+ "Size": 5573
},
"assemblies/rc.bin": {
"Size": 1235
},
"assemblies/System.Collections.Concurrent.dll": {
- "Size": 11557
+ "Size": 11553
},
"assemblies/System.Collections.dll": {
- "Size": 15441
+ "Size": 15400
},
"assemblies/System.Collections.NonGeneric.dll": {
- "Size": 7500
+ "Size": 7494
},
"assemblies/System.ComponentModel.dll": {
- "Size": 1968
+ "Size": 1967
},
"assemblies/System.ComponentModel.Primitives.dll": {
- "Size": 2593
+ "Size": 2588
},
"assemblies/System.ComponentModel.TypeConverter.dll": {
"Size": 6076
},
"assemblies/System.Console.dll": {
- "Size": 6610
+ "Size": 6609
},
"assemblies/System.Core.dll": {
- "Size": 1990
+ "Size": 1986
},
"assemblies/System.Diagnostics.TraceSource.dll": {
- "Size": 6588
+ "Size": 6584
},
"assemblies/System.dll": {
- "Size": 2342
+ "Size": 2341
},
"assemblies/System.Drawing.dll": {
- "Size": 1935
+ "Size": 1932
},
"assemblies/System.Drawing.Primitives.dll": {
- "Size": 12009
+ "Size": 12005
},
"assemblies/System.IO.Compression.Brotli.dll": {
- "Size": 11221
+ "Size": 11217
},
"assemblies/System.IO.Compression.dll": {
- "Size": 15894
+ "Size": 15897
},
"assemblies/System.IO.IsolatedStorage.dll": {
- "Size": 9907
+ "Size": 10006
},
"assemblies/System.Linq.dll": {
- "Size": 19490
+ "Size": 19433
},
"assemblies/System.Linq.Expressions.dll": {
- "Size": 164338
+ "Size": 164136
},
"assemblies/System.Net.Http.dll": {
- "Size": 65558
+ "Size": 65503
},
"assemblies/System.Net.Primitives.dll": {
- "Size": 22469
+ "Size": 22470
},
"assemblies/System.Net.Requests.dll": {
- "Size": 3627
+ "Size": 3624
},
"assemblies/System.ObjectModel.dll": {
- "Size": 8156
+ "Size": 8155
},
"assemblies/System.Private.CoreLib.dll": {
- "Size": 834087
+ "Size": 832191
},
"assemblies/System.Private.DataContractSerialization.dll": {
- "Size": 192362
+ "Size": 191999
},
"assemblies/System.Private.Uri.dll": {
- "Size": 42946
+ "Size": 42894
},
"assemblies/System.Private.Xml.dll": {
- "Size": 215916
+ "Size": 215865
},
"assemblies/System.Private.Xml.Linq.dll": {
- "Size": 16683
+ "Size": 16669
},
"assemblies/System.Runtime.dll": {
- "Size": 2773
+ "Size": 2769
},
"assemblies/System.Runtime.InteropServices.dll": {
- "Size": 3756
+ "Size": 3752
},
"assemblies/System.Runtime.Serialization.dll": {
- "Size": 1861
+ "Size": 1860
},
"assemblies/System.Runtime.Serialization.Formatters.dll": {
- "Size": 2514
+ "Size": 2512
},
"assemblies/System.Runtime.Serialization.Primitives.dll": {
- "Size": 3801
+ "Size": 3797
},
"assemblies/System.Security.Cryptography.dll": {
- "Size": 7841
+ "Size": 7839
},
"assemblies/System.Text.RegularExpressions.dll": {
- "Size": 159003
+ "Size": 158406
},
"assemblies/System.Xml.dll": {
- "Size": 1755
+ "Size": 1753
},
"assemblies/System.Xml.Linq.dll": {
- "Size": 1776
+ "Size": 1770
},
"assemblies/UnnamedProject.dll": {
- "Size": 5294
+ "Size": 5423
},
"assemblies/Xamarin.AndroidX.Activity.dll": {
"Size": 5942
@@ -191,7 +191,7 @@
"Size": 528450
},
"assemblies/Xamarin.Forms.Platform.Android.dll": {
- "Size": 337831
+ "Size": 337925
},
"assemblies/Xamarin.Forms.Platform.dll": {
"Size": 11080
@@ -209,10 +209,10 @@
"Size": 93552
},
"lib/arm64-v8a/libmonodroid.so": {
- "Size": 380736
+ "Size": 380832
},
"lib/arm64-v8a/libmonosgen-2.0.so": {
- "Size": 3166048
+ "Size": 3160360
},
"lib/arm64-v8a/libSystem.IO.Compression.Native.so": {
"Size": 723560
@@ -224,7 +224,7 @@
"Size": 154904
},
"lib/arm64-v8a/libxamarin-app.so": {
- "Size": 333784
+ "Size": 333736
},
"META-INF/android.support.design_material.version": {
"Size": 12
@@ -1979,5 +1979,5 @@
"Size": 341228
}
},
- "PackageSize": 7930717
+ "PackageSize": 7877469
}
\ No newline at end of file
diff --git a/src/Xamarin.Android.Build.Tasks/Utilities/RtxtParser.cs b/src/Xamarin.Android.Build.Tasks/Utilities/RtxtParser.cs
index ed7aa317780..d2d1f6aa42b 100644
--- a/src/Xamarin.Android.Build.Tasks/Utilities/RtxtParser.cs
+++ b/src/Xamarin.Android.Build.Tasks/Utilities/RtxtParser.cs
@@ -119,7 +119,7 @@ void ProcessRtxtFile (string file, IList result)
continue;
}
int value = items [1] != "styleable" ? Convert.ToInt32 (items [3].Trim (), 16) : -1;
- string itemName = ResourceIdentifier.GetResourceName(items [1], items [2], map, log);
+ string itemName = ResourceIdentifier.GetResourceName(ResourceParser.GetNestedTypeName (items [1]), items [2], map, log);
if (knownTypes.Contains (items [1])) {
if (items [1] != "styleable") {
result.Add (new R () {
diff --git a/tests/MSBuildDeviceIntegration/Tests/InstallAndRunTests.cs b/tests/MSBuildDeviceIntegration/Tests/InstallAndRunTests.cs
index 8e8c6b1b360..0ece2f8f233 100644
--- a/tests/MSBuildDeviceIntegration/Tests/InstallAndRunTests.cs
+++ b/tests/MSBuildDeviceIntegration/Tests/InstallAndRunTests.cs
@@ -914,6 +914,122 @@ public void CheckXamarinFormsAppDeploysAndAButtonWorks ()
}, Path.Combine (Root, builder.ProjectDirectory, "button-logcat.log")), "Button Should have been Clicked.");
}
+ [Test]
+ public void SkiaSharpCanvasBasedAppRuns ([Values (true, false)] bool isRelease, [Values (true, false)] bool addResource)
+ {
+ var app = new XamarinAndroidApplicationProject () {
+ IsRelease = isRelease,
+ PackageName = "Xamarin.SkiaSharpCanvasTest",
+ PackageReferences = {
+ KnownPackages.SkiaSharp,
+ KnownPackages.SkiaSharp_Views,
+ KnownPackages.AndroidXAppCompat,
+ KnownPackages.AndroidXAppCompatResources,
+ },
+ };
+ app.AndroidResources.Add (new AndroidItem.AndroidResource ("Resources\\values\\styles.xml") {
+ TextContent = () => @"",
+ });
+ // begin Remove these lines when the new fixed SkiaSharp is released.
+ if (addResource) {
+ app.AndroidResources.Add (new AndroidItem.AndroidResource ("Resources\\values\\attrs.xml") {
+ TextContent = () => @"
+
+ ",
+ });
+ }
+ // end
+ app.LayoutMain = app.LayoutMain.Replace ("
+ ")
+ .Replace ("", "");
+ app.MainActivity = @"using Android.App;
+using Android.OS;
+using AndroidX.AppCompat.App;
+
+using SkiaSharp;
+using SkiaSharp.Views.Android;
+
+namespace UnnamedProject
+{
+ [Activity(MainLauncher = true, Theme = ""@style/AppTheme"")]
+ public class MainActivity : AppCompatActivity
+ {
+ private SKCanvasView skiaView;
+
+ protected override void OnCreate(Bundle savedInstanceState)
+ {
+ base.OnCreate(savedInstanceState);
+
+ SetContentView(Resource.Layout.Main);
+
+ skiaView = FindViewById(Resource.Id.skiaView);
+ }
+
+ protected override void OnResume()
+ {
+ base.OnResume();
+
+ skiaView.PaintSurface += OnPaintSurface;
+ }
+
+ protected override void OnPause()
+ {
+ skiaView.PaintSurface -= OnPaintSurface;
+
+ base.OnPause();
+ }
+
+ private void OnPaintSurface(object sender, SKPaintSurfaceEventArgs e)
+ {
+ // the the canvas and properties
+ var canvas = e.Surface.Canvas;
+
+ // make sure the canvas is blank
+ canvas.Clear(SKColors.White);
+
+ // draw some text
+ var paint = new SKPaint
+ {
+ Color = SKColors.Black,
+ IsAntialias = true,
+ Style = SKPaintStyle.Fill,
+ TextAlign = SKTextAlign.Center,
+ TextSize = 24
+ };
+ var coord = new SKPoint(e.Info.Width / 2, (e.Info.Height + paint.TextSize) / 2);
+ canvas.DrawText(""SkiaSharp"", coord, paint);
+ }
+ }
+}
+";
+ using (var b = CreateApkBuilder (Path.Combine ("temp", TestName, app.ProjectName))) {
+ b.BuildLogFile = "build1.log";
+ b.ThrowOnBuildFailure = false;
+ if (!addResource) {
+ Assert.IsFalse (b.Build (app, doNotCleanupOnUpdate: true), $"Build of {app.ProjectName} should have failed.");
+ Assert.IsTrue (b.LastBuildOutput.ContainsText (isRelease ? "IL8000" : "XA8000"));
+ Assert.IsTrue (b.LastBuildOutput.ContainsText ("@styleable/SKCanvasView"), "Expected '@styleable/SKCanvasView' in build output.");
+ Assert.IsTrue (b.LastBuildOutput.ContainsText ("@styleable/SKCanvasView_ignorePixelScaling"), "Expected '@styleable/SKCanvasView_ignorePixelScaling' in build output.");
+ return;
+ }
+ Assert.IsTrue (b.Build (app, doNotCleanupOnUpdate: true), $"Build of {app.ProjectName} should have succeeded.");
+ b.BuildLogFile = "install1.log";
+ Assert.IsTrue (b.Install (app, doNotCleanupOnUpdate: true), "Install should have suceeded.");
+ AdbStartActivity ($"{app.PackageName}/{app.JavaPackageName}.MainActivity");
+ WaitForPermissionActivity (Path.Combine (Root, b.ProjectDirectory, "permission-logcat.log"));
+ ClearAdbLogcat ();
+ WaitForActivityToStart (app.PackageName, "MainActivity",
+ Path.Combine (Root, b.ProjectDirectory, "startup-logcat.log"), 15);
+ }
+ }
+
[Test]
public void CheckResouceIsOverridden ([Values (true, false)] bool useAapt2)