Android Question Calling sub from Java in "blocking" mode

EduardoElias

Well-Known Member
Licensed User
Longtime User
B4X:
    @Override
    public void onSetKeyboard() {
        ba.raiseEventFromUI(this, "ynexu_onsetkeyboard", null);

//        ba.raiseEvent(this, "ynexu_onsetkeyboard",null);

//        ba.raiseEventFromDifferentThread(this, null, 0, "ynexu_onsetkeyboard", false, null);
    }

This is an Event from a SDK loaded by my app (.aar)

This event expect that I call back passing several buttons that it will control. This parts works fine.

However there is a problem, when the event fires seems that the SDK thread continues running not waiting for my callback with parameters, and that causes the process to fail.

I have tried more than one method and all failed, those in commented lines.

Is there any other way?
 

agraham

Expert
Licensed User
Longtime User
I don't understand your comment about the 'SDK thread'. Is it running on its own thread or on the main thread?

ba.raiseEvent should be a blocking call to the event Sub that invokes the event immediately before returning to the caller. It should only be called from the main thread. The other calls post the event call to the message queue and so immediately return to the caller before the event is raised. If raiseEvent isn't behaving as expected I have no idea why.
 
Upvote 1

EduardoElias

Well-Known Member
Licensed User
Longtime User
I don't understand your comment about the 'SDK thread'. Is it running on its own thread or on the main thread?

ba.raiseEvent should be a blocking call to the event Sub that invokes the event immediately before returning to the caller. It should only be called from the main thread. The other calls post the event call to the message queue and so immediately return to the caller before the event is raised. If raiseEvent isn't behaving as expected I have no idea why.
I dont know the details on how this SDK was written, however I can see in the logcat that it keeps going besides any interference, so yes after started seems to have created its own thread, its alive !

I made a big inline Java code to interface with this SDK, it is used for POS payments, so it is full of checkings and it takes full control of the android. It fires several events to prepare things for the credit card payment and including the UI presentation. I have to pass buttons where it will use as the pinpad for passoword etc

The fact is that is not blocking and that is strange. According with the vendor, other languages incorporated this SDK with no major problems.

However this inline java code is in the same B4A module and extends the SDK class for events, I wonder if it should not be running on the same thread as B4A
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
you are not expecting anything back from your raiseEvent(), so there is no reason for it to wait...
 
Upvote 0

EduardoElias

Well-Known Member
Licensed User
Longtime User
you are not expecting anything back from your raiseEvent(), so there is no reason for it to wait...
there is a reason to wait... from this raiseEvent it will call another SDK function preparing the view in order to work.... it is called exactly to make sure that at this point in time the parameters needed will be passed thru another SDK call and then returned to the normal timeline
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
if you want your raiseEvent() to wait, it has to have a return value.
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
i find @Erel's comments regarding raiseEventfromUI a little unclear,
https://www.b4x.com/android/forum/threads/java-ba-raiseeventfromui.18047/#content
but he does state clearly that it returns nothing.

the other raiseEvent() calls can return something, but the call has to be set to receive the return value. in most cases, we simply raise the event and pass something to b4a to process when the event is raised. but if you wanted something back from raiseEvent(), i believe you have to do something like:
boolean retval = ba.raiseEvent(this, "ynexu_onsetkeyboard", someobject);, not simply ba.raiseEvent(this, "ynexu_onsetkeyboard", someobject);
in the latter case you could return whatever you wanted, but the caller isn't expecting anything, so it doesn't wait.
in the former case, the caller waits for the retval from b4a.
this is how you handle a number of webview methods that require action by b4a before proceeding (eg shouldoverrideurl, shouldintercept, geolocation permission, etc).
the b4a event has to return something to the caller (perhaps a simple true/false, perhaps a string, etc)

i thought i had grasped the op's query, but if not, i apologize. i also apologize preemptively for misunderstanding how i've been using raiseevent() all these years. other apologies may be added after lunch.
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
but he does state clearly that it returns nothing.
That's true because raiseEventfromUI and raiseEventFromDifferentThread both queue the event call onto the apps message queue and return immediately so there is nothing to actually return. By contrast raiseEvent calls the event Sub immediately by reflection and so can return whatever the event sub returns.

in the latter case you could return whatever you wanted, but the caller isn't expecting anything, so it doesn't wait.
I don't understand this. There is no waiting involved whether or not raiseEvent returns a valid value. As raiseEvent runs synchronously on the callers thread and directly invokes the event sub it is just a normal sequence of calls and returns from raiseEvent to the event sub and back to the original caller of raiseEvent.
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
wait was a poor choice of words (apology) as there is may be a handler involved. but look at b4a's core.jar, the section relating to webviewwrapper, lines 57 to 78. 2 of the 3 calls to raiseevent() involve a return value from b4a's handling of the event. i'm saying that if raiseevent() isn't expecting a return value, it doesn't matter what you return in b4a.
 
Upvote 0
Top