Search code examples
xamarin.formsxamarin.androidxamarin-binding

Xamarin Android binding does not implement interface issue


I've a java binding for android which somewhat works bar the new feature I'm trying to integrate with. Only now I have realised that the intended callback is not happening. Here are the classes (decompiled to java) in question:

At the top level we have

public interface MyPackage {
   MyPackage.Companion Companion = MyPackage.Companion.$$INSTANCE;

public static final class Companion {
      @Nullable
      private static MyEventHandler myEventHandler;
      // $FF: synthetic field
      static final MyPackage.Companion $$INSTANCE;

      @Nullable
      public final MyEventHandler getMyEventHandler() {
         return myEventHandler;
      }

      public final void setMyEventHandler(@Nullable MyEventHandler var1) {
         myEventHandler = var1;
      }

      private Companion() {
      }

      static {
         MyPackage.Companion var0 = new MyPackage.Companion();
         $$INSTANCE = var0;
      }
   }
}

MyEventHandler class:

public abstract class MyEventHandler {
   public abstract void handleEvent(@NotNull String var1, @NotNull Properties var2);
}

Properties class:

import java.util.Map;

public class Properties extends r {
    public Properties() {
    }

    Properties(Map<String, Object> var1) {
        super(var1);
    }

    public Properties a(String var1, Object var2) {
        super.b(var1, var2);
        return this;
    }
}

and the problematic r class:

public class r implements Map<String, Object> {
    private final Map<String, Object> a;
various implementations...
}

So I noticed the issue when I couldnt override the HandleEvent method at the integration level and started looking at the Binding logs and found:

Warning=>

BINDINGSGENERATOR: Warning BG8801: Invalid parameter type MyPackage...Properties in method HandleEvent in managed type MyPackage.MyEventHandler. (BG8801)

And in build logs:

message BG0000: warning BG8102: Class MyPackage....Properties has unknown base type MyPackage....r.

warning BG8801: Invalid parameter type MyPackage...Properties in method HandleEvent in managed type MyPackage.MyEventHandler.

As it was obvious r is an obfuscated class I need to make chagnes to my Metadata so I went ahead and popped in:

<attr path="/api/package[@name='MyPackage']/class[@name='r']" name="obfuscated">false</attr>

Which resulted in the R being generated but now I get the 5 following compile error:

Error CS0535: 'R' does not implement interface member 'IMap.EntrySet()' (CS0535) 
Error CS0738: 'R' does not implement interface member 'IMap.KeySet()'. 'R.KeySet()' cannot implement 'IMap.KeySet()' because it does not have the matching return type of 'ICollection'. (CS0738)
Error CS0535: 'R' does not implement interface member 'IMap.Put(Object?, Object?)' (CS0535)
Error CS0535: 'R' does not implement interface member 'IMap.PutAll(IDictionary?)' (CS0535)
Error CS0738: 'R' does not implement interface member 'IMap.Values()'. 'R.Values()' cannot implement 'IMap.Values()' because it does not have the matching return type of 'ICollection'. (CS0738)

I tried to make a managed return using

<attr path="/api/package[@name='MyPackage']/class[@name='r']/method[@name='entrySet' and count(parameter)=0]" name="managedReturn">Java.Util.IMap</attr>

With same number of compile error as above. Then I tried removing the node using:

<remove-node path="/api/package[@name='MyPackage']/class[@name='r']/method[@name='entrySet']"/>

Still no luck. :(

What am I missing here? Any pointers/suggestions will be appreciated!


Solution

  • I got arround fixing it by providing implementation of the the said methods in a partial class. Basically added a new file called R.cs under Additions folder as follows:

    namespace YourNameSpace
    {
        public partial class R
        {
            public void PutAll(System.Collections.IDictionary p0)
            {
                PutAll(p0);
            }
    
            public Java.Lang.Object Put(Java.Lang.Object key, Java.Lang.Object value)
            {
                return Put(key, value);
            }
    
            public System.Collections.ICollection EntrySet()
            {
                return EntrySet();
            }
    
            public System.Collections.ICollection KeySet()
            {
                return KeySet();
            }
    
            public System.Collections.ICollection Values()
            {
                return Values();
            }
        }
    }
    

    I couldn't get it to work by adding XML transformation, but I think there was some tooling issue.