Skip to content

Commit

Permalink
[Xamarin.Android.Build.Tasks] Ensure Library views are updated (dotne…
Browse files Browse the repository at this point in the history
…t#3218)

Fixes: dotnet#3123

Scenario:

 1. Create a Solution in which the `App.csproj` references a
    `MonoAndroid`-profile `Library.csproj` project.
 2. `Library.csproj` contains an `Android.Views.View` subclass.
 3. `Library.csproj` contains an `@(AndroidResource)` with a layout
    `.axml` file which uses the `View` from (2)
 4. `App` project uses (2) with `Activity.SetContentView()`.
 5. Build & Run the project; it works.
 6. Update the `View` subclass from (2).
 7. Build & run the project.    

Step (7) is expected to result in a successful app launch.  Instead,
it fails during process startup:

	Android.Views.InflateException: Binary XML file line #1: Binary XML file line #1: Error inflating class InflatedLibrary.CodeBehindClass occurred

Commit 373c6ed added a new `_ConvertCustomView` target to handle the
conversion of custom view to the md5 hash versions.  While it worked
*most* of the time, there was a very specific area where it was not
fixing up the custom views.

This problem only occurs when a library project code is updated, as
with step (6).  When happens next is that when the main app builds
and the library resources are then re-extracted into the
`$(IntermediateOutputPath)lp\XX\ji\res` directory.
The `<ConvertResorucesCases/>` task is then run to fixup those `res`
files with the correct casing.  Then the `<GenerateJavaStubs/>` task
is run, because the library project was updated.

However at this point the wheels fall of the wagon because the
`_ConvertCustomViews` target does NOT run.  This is because it is
only using the following inputs:

	$(_CustomViewMapFile);$(_AcwMapFile)

Neither of these files are updated in this instance.  `$(_AcwMapFile)`
will only be updated if a class or namespace are changed.  If code
within a class is changed in a way which doesn't alter the class or
namespace name, then nothing in the ACW map will need to be updated,
so we don't update the file.

The `$(_CustomViewMapFile)` is also not updated, unless resources are
added or removed.  So that doesn't change either.  The result is the
target is skipped, and we end up with a custom view which does NOT
have the correct type names.  This results in the above error.

The fix in this case is to update the Inputs of the
`_ConvertCustomView` target to have the following

	$(_CustomViewMapFile);$(_AcwMapFile);@(_AndroidResourceDest);@(_LibraryResourceDirectoryStamps)

By including these two extra items we can make sure the target runs
if either an app resource is updated or if a library project changes.

A unit test has been updated to test for this particular issue.
  • Loading branch information
dellis1972 authored and jonpryor committed Jun 14, 2019
1 parent 75cde13 commit 88572f8
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,17 @@ protected override void OnClick()
"Warning while processing resources should not have been raised.");
Assert.IsTrue (b.Build (proj, doNotCleanupOnUpdate: true), "Build should have succeeded.");
Assert.IsTrue (b.Output.IsTargetSkipped ("_GenerateJavaStubs"), "Target _GenerateJavaStubs should have been skipped");

lib.Touch ("CustomTextView.cs");

Assert.IsTrue (libb.Build (lib, doNotCleanupOnUpdate: true, saveProject: false), "second library build should have succeeded.");
Assert.IsTrue (b.Build (proj, doNotCleanupOnUpdate: true, saveProject: false), "second app build should have succeeded.");

using (var zip = ZipHelper.OpenZip (packaged_resources)) {
CheckCustomView (zip, intermediate, "lp", "0", "jl", "res", "layout", "custom_text_lib.xml");
CheckCustomView (zip, intermediate, "res", "layout", "custom_text_app.xml");
}

Assert.IsTrue (b.Clean (proj), "Clean should have succeeded.");
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<!--
<!--
***********************************************************************************************
Xamarin.Android.Common.targets
Expand Down Expand Up @@ -2307,7 +2307,7 @@ because xbuild doesn't support framework reference assemblies.

<Target Name="_ConvertCustomView"
Condition="Exists('$(_CustomViewMapFile)')"
Inputs="$(_CustomViewMapFile);$(_AcwMapFile)"
Inputs="$(_CustomViewMapFile);$(_AcwMapFile);@(_AndroidResourceDest);@(_LibraryResourceDirectoryStamps)"
Outputs="$(_AndroidStampDirectory)_ConvertCustomView.stamp">
<ConvertCustomView
CustomViewMapFile="$(_CustomViewMapFile)"
Expand Down

0 comments on commit 88572f8

Please sign in to comment.