Perhaps it is very obvious, but I am a bit stuck thinking about this and any help will be welcome...
I am developing a library with several classes. One of these classes executes some tasks in a different thread.
This thread must call a Sub in B4A, that will do some custom work. This B4A Sub has to be called synchronously (so will be executed in that thread) : it will modify some data and the thread will continue working with it.
Here is my doubt (and perhaps where I am wrong):
I think I can't use "raiseEvent","raiseEventFromDifferentThread",.... since they will be executed asynchronously. Is it right?
If so, how can I directly call a BA Sub from Java?
Does your Java code have compile-time access to the object that "owns" the Sub (Activity, Service or instance of a Class)? If so, just call it as you would any Java function. B4A Subs will be lower-cased and an underscore "_" will be prepended to the Sub name.
If not, you can use anywheresoftware.b4a.keywords.Common.CallSubNew.
Alternatively, you can do the following (this is Java reflection):
B4X:
Class[] parameterTypes = {}; //This will be an array indicating the types of the arguments to be passed to your Sub
Object o = c.getDeclaredMethod("_" + SubName.toLowerCase(), parameterTypes).invoke(OwningObject, new Object[]{});
//That new Object Array will be the arguments passed to OwningObject.SubName. The Object o is the return value of OwningObject.SubName
In your most recent post, you're using "main" as the second argument to CallSubNew. That's a String. It should be the object itself, main. Also, are you sure you're using the correct ba? If you're calling this Java code from within the Main Activity, you'll probably want to use the activityBA. It is for this reason that I prefer my last option (using Java reflection). No messing about with BAs....
Now it is solved! --> The reason it didn't work was that during my tests I was invoquing everything (initializing my class and make the call) in Activity_Create, and this call did not take effect (but didn't throw any error)
Is there any advantage (in terms of efficiency, or other factors I should care about) on using one over the other? This will be called on each frame delivered by the camera and the processed results will be drawn on a surfaceView.
1. This means that your code is raising synchronous events. Make sure to mark the relevant method with @RaisesSynchronousEvents.
2. Use ba.raiseEvent2 and set the allowDuringPause parameter to pause.