Skip to content

Commit

Permalink
[Xamarin.Android.Build.Tasks] Resource.designer.cs shouldn't be empty (
Browse files Browse the repository at this point in the history
…#3177)

Context: #3169

In 36c52c2, I fixed some of the weirdness from the test case in
Issue #3169, but there is another problem: `Resource.designer.cs` was
empty!

This is actually an issue because Xamarin.Forms 4.0 uses
`@(AndroidResource)` files.  If there is a case where
`Resource.designer.cs` isn't generated, then those resource IDs will
be wrong, causing a runtime crash:

	Java.Lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v7/appcompat/R$drawable; ---> Java.Lang.ClassNotFoundException: Didn't find class "android.support.v7.appcompat.R$drawable" on path: DexPathList[[zip file "/system/framework/org.apache.http.legacy.boot.jar", zip file "/data/app/com.companyname.Demo2.Android-PozTNMz4ZBMXaHx-doetdQ==/base.apk"],nativeLibraryDirectories=[/data/app/com.companyname.Demo2.Android-PozTNMz4ZBMXaHx-doetdQ==/lib/arm64, /data/app/com.companyname.Demo2.Android-PozTNMz4ZBMXaHx-doetdQ==/base.apk!/lib/arm64-v8a, /system/lib64]]
	   --- End of inner exception stack trace ---
	  at Java.Interop.JniEnvironment+InstanceMethods.CallNonvirtualVoidMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniObjectReference type, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x00089] in <372c976a2c5d45cb9abb001729e14dbf>:0
	  at Java.Interop.JniPeerMembers+JniInstanceMethods.InvokeVirtualVoidMethod (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) [0x0005d] in <372c976a2c5d45cb9abb001729e14dbf>:0
	  at Android.App.Activity.OnCreate (Android.OS.Bundle savedInstanceState) [0x00031] in <547679cba0d64c03859bc6ab9919a165>:0
	  at Xamarin.Forms.Platform.Android.FormsAppCompatActivity.OnCreate (Android.OS.Bundle savedInstanceState) [0x0001d] in <02288cf327c341c79f8385d5db4c09bf>:0
	  at Demo2.Droid.MainActivity.OnCreate (Android.OS.Bundle savedInstanceState) [0x00001] in <16681ab0b39d4abe8efd53e748c930e4>:0
	  at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_savedInstanceState) [0x00011] in <547679cba0d64c03859bc6ab9919a165>:0
	  at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.7(intptr,intptr,intptr)
	  --- End of managed Java.Lang.NoClassDefFoundError stack trace ---


Looking through the code, the sequence of events is a bit bizarre:

 1. `<GenerateResourceDesigner/>` writes to a temp file using
    `MonoAndroidHelper.CopyIfStringChanged()`.
 2. `<CopyIfChanged/>` moves from the temp file to
    `Resources\Resource.designer.cs` if there were changes.
 3. `<CreateAndroidResourceStamp/>` basically does a "touch" and
    appends a newline to `Resources.designer.cs`???  It also touches
    a stamp/flag file.

The steps didn't make sense--it seems they all will run every time.

It seemed like we just needed to clean things up:

 1. `<GenerateResourceDesigner/>` writes directly to
    `Resources\Resource.designer.cs`, relying on
    `MonoAndroidHelper.CopyIfStringChanged()`.
 2. We get rid of `<CreateAndroidResourceStamp/>`.
 3. We just use `<Touch/>` for the flag file, and add it to
    `@(FileWrites)` appropriately.

I think these changes will make this scenario a bit more reliable and
improve performance slightly.

I also updated the `AllResourcesInClassLibrary` test to verify
`Resource.designer.cs` *exists* and is non-empty.
  • Loading branch information
jonathanpeppers authored and jonpryor committed Jun 7, 2019
1 parent 072f69b commit ea6853a
Show file tree
Hide file tree
Showing 6 changed files with 17 additions and 56 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,9 @@ private void WriteFile (string file, CodeTypeDeclaration resources, string langu
}
}

MonoAndroidHelper.CopyIfStringChanged (code, file);
if (MonoAndroidHelper.CopyIfStringChanged (code, file)) {
Log.LogDebugMessage ($"Writing to: {file}");
}
}

private void AddRename (string android, string user)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,9 @@ public void CheckResourceDesignerIsUpdatedWhenReadOnly (bool isRelease, ProjectL
android:layout_height=""wrap_content""
android:text=""Hello""
/>
<TextView
android:id=""@+id/myText""
/>
</LinearLayout>";
Assert.IsTrue (b.Build (proj), "Build should have succeeded.");
Assert.IsTrue ((File.GetAttributes (designerPath) & FileAttributes.ReadOnly) != FileAttributes.ReadOnly,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3839,6 +3839,11 @@ public void AllResourcesInClassLibrary ([Values (true, false)] bool useAapt2)

var r_txt = Path.Combine (Root, appBuilder.ProjectDirectory, app.IntermediateOutputPath, "R.txt");
FileAssert.Exists (r_txt);

var resource_designer_cs = Path.Combine (Root, appBuilder.ProjectDirectory, "Resources", "Resource.designer.cs");
FileAssert.Exists (resource_designer_cs);
var contents = File.ReadAllText (resource_designer_cs);
Assert.AreNotEqual ("", contents);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,6 @@
<Compile Include="Tasks\CreateNativeLibraryArchive.cs" />
<Compile Include="Tasks\GetImportedLibraries.cs" />
<Compile Include="Tasks\GetAdditionalResourcesFromAssemblies.cs" />
<Compile Include="Tasks\CreateAndroidResourceStamp.cs" />
<Compile Include="Tasks\CollectLibraryAssets.cs" />
<Compile Include="Tasks\ImportJavaDoc.cs" />
<Compile Include="Tasks\MDoc.cs" />
Expand Down
23 changes: 6 additions & 17 deletions src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved.
<UsingTask TaskName="Xamarin.Android.Tasks.ScanAssemblies" AssemblyFile="Xamarin.Android.Build.Tasks.dll" />
<UsingTask TaskName="Xamarin.Android.Tasks.CheckProjectItems" AssemblyFile="Xamarin.Android.Build.Tasks.dll" />
<UsingTask TaskName="Xamarin.Android.Tasks.CheckDuplicateJavaLibraries" AssemblyFile="Xamarin.Android.Build.Tasks.dll" />
<UsingTask TaskName="Xamarin.Android.Tasks.CreateAndroidResourceStamp" AssemblyFile="Xamarin.Android.Build.Tasks.dll" />
<UsingTask TaskName="Xamarin.Android.Tasks.CollectLibraryAssets" AssemblyFile="Xamarin.Android.Build.Tasks.dll" />
<UsingTask TaskName="Xamarin.Android.Tasks.ParseAndroidWearProjectAndManifest" AssemblyFile="Xamarin.Android.Build.Tasks.dll" />
<UsingTask TaskName="Xamarin.Android.Tasks.PrepareWearApplicationFiles" AssemblyFile="Xamarin.Android.Build.Tasks.dll" />
Expand Down Expand Up @@ -1759,7 +1758,7 @@ because xbuild doesn't support framework reference assemblies.
<GenerateResourceDesigner
Condition="'$(_AndroidResourceDesignerFile)' != ''"
ContinueOnError="$(DesignTimeBuild)"
NetResgenOutputFile="$(ResgenTemporaryDirectory)\$(AndroidResgenFilename)"
NetResgenOutputFile="$(_AndroidResourceDesignerFile)"
JavaResgenInputFile="$(_GeneratedPrimaryJavaResgenFile)"
Namespace="$(AndroidResgenNamespace)"
ProjectDir="$(ProjectDir)"
Expand All @@ -1773,23 +1772,13 @@ because xbuild doesn't support framework reference assemblies.
JavaPlatformJarPath="$(JavaPlatformJarPath)"
/>

<!-- Only copy if the file contents changed, so users only get Reload? dialog for real changes -->
<CopyIfChanged
SourceFiles="$(ResgenTemporaryDirectory)\$(AndroidResgenFilename)"
DestinationFiles="$(_AndroidResourceDesignerFile)"
Condition="'$(_AndroidResourceDesignerFile)' != '' And Exists ('$(ResgenTemporaryDirectory)\$(AndroidResgenFilename)')"
/>

<!-- Delete our temporary directory -->
<RemoveDirFixed Directories="$(ResgenTemporaryDirectory)" />

<!-- If there are no _AndroidResource items, create a blank file -->
<CreateAndroidResourceStamp
Condition="'$(_AndroidResourceDesignerFile)' != ''"
AndroidResgenFile="$(_AndroidResourceDesignerFile)"
AndroidResourceDest="@(_AndroidResourceDest)"
MonoAndroidResDirIntermediate="$(MonoAndroidResDirIntermediate)"
AndroidResgenFlagFile="$(_AndroidResgenFlagFile)" />

<Touch Files="$(_AndroidResgenFlagFile)" AlwaysCreate="True" />
<ItemGroup>
<FileWrites Include="$(_AndroidResgenFlagFile)" />
</ItemGroup>
</Target>

<Target Name="_CreateManagedLibraryResourceArchive"
Expand Down

0 comments on commit ea6853a

Please sign in to comment.