From 9efe81587ab4586cb6e9f5bdb7682daeb6dd9776 Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Mon, 7 Aug 2017 12:59:21 +0100 Subject: [PATCH] [Xamarin.Android.Build.Tasks] Sample for Microsoft Intune is failing - System.NullReferenceException at IntuneMAMSampleAndroid.EntryActivity.OnCreate Fixes https://bugzilla.xamarin.com/show_bug.cgi?id=57279 The DesignTimeBuilds are causing a bit of a problem. Because they are being run as soon as the project is loaded, it does result in the `_UpdateAndroidResGen` thinking that the resources are up to date. This results in the following find . -iname R.java | xargs grep EntryActivityStartButton ./IntuneMAMSampleAndroid/obj/AnyCPU/Debug/android/com/microsoft/intune/mam/R.java: public static final int EntryActivityStartButton=0x7f070000; ./IntuneMAMSampleAndroid/obj/AnyCPU/Debug/android/microsoftintunemamsampleandroid/microsoftintunemamsampleandroid/R.java: public static final int EntryActivityStartButton=0x7f070000; ./IntuneMAMSampleAndroid/obj/AnyCPU/Debug/android/src/android/support/v4/R.java: public static int EntryActivityStartButton=0x7f0c0050; ./IntuneMAMSampleAndroid/obj/AnyCPU/Debug/android/src/android/support/v7/appcompat/R.java: public static int EntryActivityStartButton=0x7f0c0050; ./IntuneMAMSampleAndroid/obj/AnyCPU/Debug/android/src/com/microsoft/intune/mam/R.java: public static final int EntryActivityStartButton=0x7f0c0050; ./IntuneMAMSampleAndroid/obj/AnyCPU/Debug/android/src/microsoftintunemamsampleandroid/microsoftintunemamsampleandroid/R.java: public static final int EntryActivityStartButton=0x7f0c0050; Note that the `EntryActivityStartButton` value is different, they should all be the same. This is because the `_UpdateAndroidResGen` target was NOT running. Fortunately commit 1cd582ec adds `$(DesignTimeBuild)` to the list of properties in the `@(_PropertyCacheItems)` ItemGroup. So we can now use the `$(_AndroidBuildPropertiesCache)` property to detect when we are moving from a DesignTimeBuild into a normal Build. This means the resources are then generated correctly. --- .../AndroidUpdateResourcesTest.cs | 23 ++++++++++++++++--- .../Xamarin.Android.Common.targets | 3 ++- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AndroidUpdateResourcesTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AndroidUpdateResourcesTest.cs index 1d2651cae24..fd082a697a0 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AndroidUpdateResourcesTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AndroidUpdateResourcesTest.cs @@ -9,6 +9,7 @@ using Microsoft.Build.Framework; using System.Xml.Linq; using System.Security.Cryptography; +using System.Text.RegularExpressions; namespace Xamarin.Android.Build.Tests { @@ -37,6 +38,8 @@ public void RepetitiveBuild () [Test] public void DesignTimeBuild ([Values(false, true)] bool isRelease) { + var regEx = new Regex (@"(?([a-zA-Z_0-9])+)\slibrary_name=(?([0-9A-Za-z])+);", RegexOptions.Compiled | RegexOptions.Multiline ); + var path = Path.Combine (Root, "temp", $"DesignTimeBuild_{isRelease}"); var cachePath = Path.Combine (path, "Cache"); var envVar = new Dictionary () { @@ -71,8 +74,8 @@ public void DesignTimeBuild ([Values(false, true)] bool isRelease) }, }; - using (var l = CreateDllBuilder (Path.Combine (path, lib.ProjectName))) { - using (var b = CreateApkBuilder (Path.Combine (path, proj.ProjectName))) { + using (var l = CreateDllBuilder (Path.Combine (path, lib.ProjectName), false, false)) { + using (var b = CreateApkBuilder (Path.Combine (path, proj.ProjectName), false, false)) { l.Verbosity = LoggerVerbosity.Diagnostic; Assert.IsTrue(l.Clean(lib), "Lib1 should have cleaned successfully"); Assert.IsTrue (l.Build (lib), "Lib1 should have built successfully"); @@ -83,12 +86,26 @@ public void DesignTimeBuild ([Values(false, true)] bool isRelease) "first build failed"); Assert.IsTrue (b.LastBuildOutput.Contains ("Skipping download of "), "failed to skip the downloading of files."); + var items = new List (); + foreach (var file in Directory.EnumerateFiles (Path.Combine (path, proj.ProjectName, proj.IntermediateOutputPath, "android"), "R.java", SearchOption.AllDirectories)) { + var matches = regEx.Matches (File.ReadAllText (file)); + items.AddRange (matches.Cast ().Select(x => x.Groups ["value"].Value)); + } + var first = items.First (); + Assert.IsTrue (items.All (x => x == first), "All Items should have matching values"); WaitFor (1000); b.Target = "Build"; Assert.IsTrue (b.Build (proj, doNotCleanupOnUpdate: true, parameters: new string [] { "DesignTimeBuild=false" }, environmentVariables: envVar), "second build failed"); Assert.IsFalse(b.Output.IsTargetSkipped ("_BuildAdditionalResourcesCache"), "_BuildAdditionalResourcesCache should have run."); - Assert.IsTrue (b.LastBuildOutput.Contains($"Downloading {url}") || b.LastBuildOutput.Contains ($"reusing existing archive: {zipPath}"), $"{url} should have been downloaded."); + Assert.IsTrue (b.LastBuildOutput.Contains ($"Downloading {url}") || b.LastBuildOutput.Contains ($"reusing existing archive: {zipPath}"), $"{url} should have been downloaded."); Assert.IsTrue (File.Exists (Path.Combine (extractedDir, "1", "content", "android-N", "aapt")), $"Files should have been extracted to {extractedDir}"); + items.Clear (); + foreach (var file in Directory.EnumerateFiles (Path.Combine (path, proj.ProjectName, proj.IntermediateOutputPath, "android"), "R.java", SearchOption.AllDirectories)) { + var matches = regEx.Matches (File.ReadAllText (file)); + items.AddRange (matches.Cast ().Select (x => x.Groups["value"].Value)); + } + first = items.First (); + Assert.IsTrue (items.All (x => x == first), "All Items should have matching values"); } } } diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets index 645757df281..b72a1aaeeb3 100755 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets @@ -1244,7 +1244,8 @@ because xbuild doesn't support framework reference assemblies. $(MSBuildAllProjects); @(_AndroidResourceDest); @(_LibraryResourceDirectoryStamps); - @(_AdditonalAndroidResourceCachePaths->'%(Identity)\cache.stamp') + @(_AdditonalAndroidResourceCachePaths->'%(Identity)\cache.stamp'); + $(_AndroidBuildPropertiesCache)