Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Issue while creating Android binding for Xamarin

I am trying to create a binding project for a library that our organisation is already created. I have added the .aar file and when I try to build I am getting the below two error.

 Error JAVAC0000:  error: OnCompletionListenerImplementor is not abstract and does not override abstract method onCompletion(LockEvent,int,Metadata) in OnCompletionListener

public class OnCompletionListenerImplementor (JAVAC0000)

Error JAVAC0000:  error: SingleStepView_OnSelectionListenerImplementor is not abstract and does not override abstract method onSelected(Metadata,LockEvent) in OnSelectionListener
public class SingleStepView_OnSelectionListenerImplementor
 (JAVAC0000)

In the API.xaml

It is generated like this,

<interface abstract="true" deprecated="not deprecated" final="false" name="OnCompletionListener" static="false" visibility="public" jni-signature="Lno/zedoapp/zebra/key_ui/ui/listener/OnCompletionListener;"></interface>
<interface abstract="true" deprecated="not deprecated" final="false" name="SingleStepView.OnSelectionListener" static="true" visibility="public" jni-signature="Lno/zedoapp/zebra/key_ui/ui/view/SingleStepView$OnSelectionListener;"></interface>

Also I have noticed in Object browser that the class is not generating properly.

public interface IOnCompletionListener : IJavaObject, IDisposable, IJavaPeerable
{
}

internal sealed class IOnCompletionListenerImplementor : Java.Lang.Object, IOnCompletionListener, IJavaObject, IDisposable, IJavaPeerable
{
    public IOnCompletionListenerImplementor ()
        : base (JNIEnv.StartCreateInstance ("mono/Lno/zedoapp/zebra/key_ui/ui/listener/OnCompletionListenerImplementor", "()V"), JniHandleOwnership.TransferLocalRef);

    internal static bool __IsEmpty (IOnCompletionListenerImplementor value);
}


public interface IOnSelectionListener : IJavaObject, IDisposable, IJavaPeerable
{
}

internal sealed class IOnSelectionListenerImplementor : Java.Lang.Object, IOnSelectionListener, IJavaObject, IDisposable, IJavaPeerable
{
        public IOnSelectionListenerImplementor ()
            : base (JNIEnv.StartCreateInstance ("mono/Lno/zedoapp/zebra/key_ui/ui/view/SingleStepView_OnSelectionListenerImplementor", "()V"), JniHandleOwnership.TransferLocalRef);

        internal static bool __IsEmpty (IOnSelectionListenerImplementor value);
}

Can someone help me to interpret the issue and to solve my binding

like image 266
Nitha Paul Avatar asked Feb 12 '20 09:02

Nitha Paul


People also ask

How do I set bindings in Xamarin?

To set the data binding, use the following two members of the target class: The BindingContext property specifies the source object. The SetBinding method specifies the target property and source property.

What is the default binding mode in Xamarin forms?

The default binding mode is OneWayToSource . When a data binding is set on the SelectedItem property to reference a source property in a ViewModel, then that source property is set from the ListView selection. However, in some circumstances, you might also want the ListView to be initialized from the ViewModel.

Is Xamarin being discontinued?

In May 2020, Microsoft announced that Xamarin. Forms, a major component of its mobile app development framework, would be deprecated in November 2021 in favour of a new .


1 Answers

The documentation at this link is somewhat misleading in my opinion.

It tells you that you need to give the generated EventArgs classes different names because the binding generator does not play well with generics and can't tell the different between the 2 Java interfaces. You do that by adding transform rules like the below to the Medata.xml file:

<attr path="/api/package[@name='com.whatever.android']/interface[@name='InterfaceListenerA']/method[@name='onJavaInterfaceMethodName']"
    name="argsType">InterfaceListenerAEventArgs</attr>

<attr path="/api/package[@name='com.whatever.android']/interface[@name='InterfaceListenerB']/method[@name='onJavaInterfaceMethodName']"
    name="argsType">InterfaceListenerBEventArgs</attr>

In my case this allowed my binding project to build. But when I tried to reference it in an Xamarin Android project and build it, I get the above error.

What the docs don't tell you is that when you do this the generated event name will mean that the code no longer implements the required interface in the generated java code. To make it do that you need to map the java interface method to the renamed C# event property name. To do that I added rules like these:

<attr path="/api/package[@name='com.whatever.android']/interface[@name='InterfaceListenerA']/method[@name='onJavaInterfaceMethodName']"
    name="managedName">InterfaceListenerA</attr>

<attr path="/api/package[@name='com.whatever.android']/interface[@name='InterfaceListenerB']/method[@name='onJavaInterfaceMethodName']"
    name="managedName">InterfaceListenerB</attr>

Note: The managed name is not necessarily the same as the Java interface name - it's whatever name you've given to each of the new EventArgs classes without the "EventArgs" suffix.

like image 178
Breeno Avatar answered Oct 12 '22 20:10

Breeno