Is it possible to make void delegate extend Runnable for Java


(James Esword) #1

@ck
As below code shown, currently I have to use a wrapper to pass my Action delegate to an Java API:

public delegate void Action();

#if COOPER
public class ARunnable : Runnable {
    private readonly Action mAction;
    public ARunnable(Action action) {
        mAction = action;
    }
    public void run() => mAction();
}
#endif

public class TestClass {
    private Handler mHandler = new Handler();
    public void test(Action action) {
        mHandler.post(new ARunnable(action));
    }
}

And I’ve known that Elements will compile “Action” to an Java interface:

public interface Action {
void Invoke();
}

Since java.lang.Runnable is a very basic and standard Java interface, I think it’s better to make the generated Action interface to extend it, like what Elements have done to a void lambda expression.

Or be more advanced, Elements can auto replace all void delegate types with java.lang.Runnable directly only for Java, then there’s no cross-platform overhead to communicate with standard Java API.


(Carlo Kok) #2

Something to consider yes. However you can always (for now) use:

 mHandler.post( () => action());

(James Esword) #3

Nope…Lambda exp currently is very expensive for Java on Elements.

If you write mHandler.post( ()=>action() ); in different classes, you will find there’re multiple anonymous class definitions are generated which are exactly the same except for their names.

That’s why I use a self-defined ARunnable instead.


(Carlo Kok) #4

True. because lambdas are always distinct (can’t really compare vastly different code)


(James Esword) #5

And you know Android has 64k methods limit…So it’s worth to do more optmizations to reduce unnecessary class definitions.


(Carlo Kok) #6

Agreed. For what it’s worth you can easily change it locally:

we’re going to discuss this and consider it.