dotnet / android

.NET for Android provides open-source bindings of the Android SDK for use with .NET managed languages such as C#
MIT License
1.94k stars 533 forks source link

Adding .aar and .jar dependencies without C# bindings in Android Java Library Binding Project #8190

Closed bbarc closed 1 year ago

bbarc commented 1 year ago

Android application type

.NET Android (net7.0-android, etc.)

Affected platform version

Visual Studio Professional 2022 - 17.6.4 on Windows

Description

I have attached the sample code below:

FooBazBar.Client2.zip

In this project I have the FooForBinding-release.aar file intended for binding, however it depends on 3 other java/kotlin libraries which must not get C# bindings. I have achieved this by setting the following elements in .csproj and Metadata.xml:

My other approaches failed.

The existing documentation helped me a bit, but did not cover the whole process. Moreover, I am not sure if that is the intended way of doing it.

Should there be any other working and documented solution for this type of tasks?

Steps to Reproduce

  1. Just run the attached Android Application without any exceptions being thrown.

Did you find any workaround?

I am not sure if my solution is a workaround or there should be any better approach.

Relevant log output

No response

jonathanpeppers commented 1 year ago

It seems like you should be able to do this (and that's it):

<AndroidLibrary Update="ReferencedBarK.jar" Bind="false" />
<AndroidLibrary Update="ReferencedBazJ.jar" Bind="false" />

This would allow the binding generator to "find" the referenced libraries if needed and produce a binding, but you shouldn't have to use <remove-node/>.

Was this the doc you found already:

bbarc commented 1 year ago

I have followed the doc you mentioned, just replacing the Include attribute with the Update one in <AndroidLibrary/> element.

using Update generates the following content of Foo.Binding.dll image

whereas using Include gives me additional C# bindings: image

In both cases Foo.Binding.aar containing renamed ReferencedBazJ.jar and ReferencedBarK.jar files is created in FooBazBar.Client/Foo.Binding/bin/Debug/net7.0-android directory. And that is fine.

The problem seems to be with .aar, especially when using <AndroidLibrary Update="FooNonBinding-release.aar" Bind="false" />. In this case FooNonBinding-release.aar is not copied to FooBazBar.Client/Foo.Binding/bin/Debug/net7.0-android and I get the runtime exception in the sample Android application: image

In case of using Include attribute here, like <AndroidLibrary Include="FooNonBinding-release.aar" Bind="false" /> and with <remove-node path="/api/package[starts-with(@name,'com.example.foononbinding')]" /> removed from Metadata.xml I get an additional C# bindings in .dll: image

They are not desired. I have the requirement of only Com.Example.Foofrobinding C# bindings being present in .dll and my sample app not throwing any runtime exceptions.

Is there any other way to achieve both goals?

jonathanpeppers commented 1 year ago

It's possible the entry:

<AndroidLibrary Update="FooNonBinding-release.aar" Bind="false" />

Maybe this doesn't flow properly between ProjectReference, but if your class library was a NuGet package, I suspect it would work fine.

Let me review your project above, and see if this is the case.

jonathanpeppers commented 1 year ago

@bbarc the sample above seemed like it worked for me. The app ran successfully on a Pixel 5.

The .aar files were copied to the output directory:

image

And then when I review a .binlog of the app, I see it using the .aar files as well:

image

So that brings up two thoughts:

Thanks!

ghost commented 1 year ago

Hi @bbarc. We have added the "need-info" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.

bbarc commented 1 year ago

@jonathanpeppers please confirm if you have run the sample under the following conditions:

  1. not using <remove-node/> in ..FooBazBar.Client\Foo.Binding\Transforms\Metadata.xml file;
  2. having <AndroidLibrary Update="FooNonBinding-release.aar" Bind="false" /> set in ..FooBazBar.Client\Foo.Binding\Foo.Binding.csproj file
  3. getting no C# Com.Example.Foononbinding.FooSample bindings inside the ..FooBazBar.Client\Foo.Binding\bin\Debug\net7.0-android\Foo.Binding.dll

Thank you!

jonathanpeppers commented 1 year ago

@bbarc can you update the .zip file above? So, someone can download and run it to see the exact issue.

bbarc commented 1 year ago

@jonathanpeppers the .zip file above has been updated.

jonathanpeppers commented 1 year ago

I think I see the issue, there is a line like this in our MSBuild targets:

<!-- .aar files should be copied to $(OutputPath) in .NET 6-->
<None Include="@(LibraryProjectZip)" ... CopyToOutputDirectory="PreserveNewest" Link="%(Filename)%(Extension)" />

But this isn't setup for .aar files when Bind="false".

I could workaround the problem in Foo.Binding.csproj by adding:

<AndroidLibrary Update="FooNonBinding-release.aar" Bind="false" />
<!-- Workaround issue copying .aar file to output directory -->
<None Include="FooNonBinding-release.aar" CopyToOutputDirectory="PreserveNewest" />

Good find! Thanks for reporting.