How to call foreign code with a function parameter?

I have the following Uno code for calling a native method:

public static object Test(Context context, object[] args)
{
    TestNative((Action)args[0]);
    return null;
}

[Foreign(Language.Java)]
public static extern(Android) void TestNative(Action action)
@{
    android.util.Log.i("FuseForeignCode", "TestNative");
@}

If I alter the code so that there is no argument to the native method then it works fine, ie. the native method call is successful.
However, when I have the Action argument (as shown in the code) I get an error and the app dies at the method call:

F/libc    (28700): Fatal signal 11 (SIGSEGV), code 1, fault addr 0x7 in tid 28888 (Thread-3730)

The JS call looks like this:

Foo.Test(function () {
    debug_log("Foo")
})

Is this the correct way to call a native method with a callback?

Ultimately I want to do this:

[Foreign(Language.Java)]
public static extern(Android) void TestNative(Action action)
@{
    action.run();
@}

Which should print “Foo”. Am I on the right track?

Many thanks.

Also, if I want to do something for non-mobile, like this:

public static extern(!Mobile) void TestNative(Action action)
{
    action();
}

I get: Unable to cast object of type ‘Fuse.Scripting.V8.Function’ to type ‘System.Action’

Which makes sense I guess, but when I tried the change the type I just got: Fuse.Scripting does not contain type or namespace ‘V8’.

How should this work?

Thanks.

I don’t think you’re on the right path. Fuse already has an EventEmitter that emits events you can subscribe to. Several Fuse modules are based on EventEmitter, for example, Lifecycle.

Please check those links and let us know if that helps you achieve what you’re after. If it doesn’t, please explain the specific use case you have in mind.

Ok, I see. Sounds like I am on the wrong track!

Do you have any hints on how to emit an event from Java foreign code? I can’t seem to find any examples at the moment.

So that’s a pretty deep rabbit hole. Here’s something that I could find:

  1. There is a Uno class that is an EventEmitter: WebSocketModule
  2. It instantiates and assigns some properties (those EventEmitter callbacks, actually) on another Uno class, which then holds the Foreign code implementation for the actual target-specific logic: WebSocketClient

That’s as far as I can help you :slight_smile:

Actually, maybe I should explain the use case…

My app has an ApduService (for HCE) running in the background. I have created a Java class (called Hce) that will connect to this service and listen for data from it. When the data is received I want to invoke a JS function/callback to send that data to the JS layer in the app.

So in JS I want something like:

Hce.init(function (message) {
    debug_log("Received: " + message)
})

(Where Hce is a native Java class)

So essentially I want to pass a JS callback down into the Java layer and invoke it from there. Or at least that’s what I was trying to do :slight_smile: !

Looking at the foreign code docs it seemed as though it was possible to pass Actions etc into foreign code. But maybe that’s not the way…

So if there is another way that is better (such as using EventEmitters) then that is fine. However, I don’t understand how to invoke the emitter from Java or how to register a listener in JS.

Any ideas on how to do this?

Thanks

This is exactly what your first post in this thread should have been. Thanks!

I believe the last 2 links that I shared show you exactly how to pass Actions down to Foreign code (Java and Objective-C). If the examples don’t get you any further, I’ll try to get The People Who Know to look at this.

Ok thanks Uldis :slight_smile:

Anyone else (like Chris) who would have an idea?

Essentially I “just” need to asynchronously send data from Java to JS. Any way would be fine, even broadcasting Intents or something.

Cheers

Thanks - I just read your last reply!

Let me check the links.