Java Question BA.submitRunnable + XMLRPC

westingenieria

Active Member
Licensed User
Longtime User
First of all thank you very much for this great RAD.

Im wondering how to manage the send/recieve string with XMLRPC lib.. i was using AsyncTask but i saw a post of Erel that said he didnt recommend to use AsyncTask and its better to use BA.submitRunnable... well im trying to do that.. this is my code (java):

B4X:
public String stringCall(final String Method, final Object p0, final int TaskId)
  {
     String stringx;
     stringx = "";
     if (BA.isTaskRunning(this, TaskId))      
         return stringx;
     
     Runnable runnable = new Runnable()
     {
      public void run() {
         try {
            asd = (String)XMLRPC.this.client.call(Method,p0);
         }catch (XMLRPCException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            asd = "";
         }
       }
     };
     BA.submitRunnable(runnable, this, TaskId);
     return asd;
  }

b4a call code:

B4X:
XMLRPC1.initXMLRPCClient(sUrl)
sOut= XMLRPC1.stringCall(sService, sIn, 0)

The big problem of this is that the Main UI Thread stucks (waiting for the response -> stringCall() ) It stuck for about 4 seconds.. depending on the sIn size.

So my question is... what is wrong with my code? must i use "RaiseEventFromDifferentThread" ? how can i implement BA.submitRunnable on my stringCall() method...

Hope someone can help me. Thank you very much.

PD. my english sucks i know.. :sign0013:
 

agraham

Expert
Licensed User
Longtime User
It looks almost correct. You cannot expect asd to return any value because your task will most probably not even have started when you get to that line. So yes, you need to use RaiseEventFromDifferentThread to return the value, and also within your catch block in case of error.

B4X:
catch (Exception e)
 {
      ba.setLastException(e);
      ba.raiseEventFromDifferentThread(AsyncStreams.this, null, 0, eventName + "_error", false, null);
}
 

westingenieria

Active Member
Licensed User
Longtime User
Thank you very much! ill try "raiseEventFromDIfferentThread"... when you say AsyncStream.this .. thats mean XMLRPC.this in my case? sorry im a little confuse with that.

B4X:
ba.raiseEventFromDifferentThread(XMLRPC.this, null, 0, eventName + "_success", false, null);
 

westingenieria

Active Member
Licensed User
Longtime User
hahaha ok no problem, thank you very much. I have this code right now but it seems that the main ui thread still stuck waiting for response...

B4X:
public String stringCall(final String Method, final Object p0, final int TaskId)
  {
     String stringx;
     stringx = "";
     if (BA.isTaskRunning(this, TaskId))      
         return stringx;
     
     Runnable runnable = new Runnable()
     {
      public void run() {
         try {
            asd = (String)XMLRPC.this.client.call(Method,p0);
            ba.raiseEventFromDifferentThread(XMLRPC.this.client, null, 0, eventName + "_success", false, null);
         }catch (Exception e) {
            ba.setLastException(e);
             ba.raiseEventFromDifferentThread(XMLRPC.this.client, null, 0, eventName + "_error", false, null);
            asd = "";
         }
       }
     };
     BA.submitRunnable(runnable, this, TaskId);
     return asd;
  }
 

agraham

Expert
Licensed User
Longtime User
As I said before there is no point in returning asd from stringCall as the Runnable will not have been run. You need to return the result in raiseEventFromDifferentThread and deal with it in the Event.

B4X:
Runnable runnable = new Runnable()
{
        public void run() {
            String asd = "";
            try {
                asd = (String)XMLRPC.this.client.call(Method,p0);
                ba.raiseEventFromDifferentThread(XMLRPC.this.client, null, 0, eventName + "_success", false, new Object[] { asd });
            }catch (Exception e) {
                ba.setLastException(e);
                ba.raiseEventFromDifferentThread(XMLRPC.this.client, null, 0, eventName + "_error", false, null);
}
 

westingenieria

Active Member
Licensed User
Longtime User
Ok i understand that so i have this sub in my b4a code:

B4X:
sub timer_tick
....
XMLRPC1.initXMLRPCClient(sUrl)
stringCall(sService,sIn)
Log("Response XMLRPC: " & sOut)
....
end sub

Sub xmlrpc1_success(valueAs String)
   sOut = value
End Sub


I CANT GET INTO xmlrpc1_success ... i used
B4X:
ba.subExists(XMLRPC.this.eventName + "_success")
to know if the sub exist and its ok.. but my variable sOut is empty, that means that i never go into xmlrpc1_success... whats happend here.. am i confuse with someting?

java code:
B4X:
  public void stringCall(final String Method, final Object p0)
  throws XMLRPCException
  {    
     if (BA.isTaskRunning(XMLRPC.this, 0)){
        asd = "";
     }
     Runnable runnable = new Runnable()
     {
      String asd = "";
      public void run() {
         try {
            asd = (String)XMLRPC.this.client.call(Method,p0);
            ba.raiseEventFromDifferentThread(XMLRPC.this.client, XMLRPC.this, 0, XMLRPC.this.eventName + "_success", false, new Object[] { asd });
         }catch (XMLRPCException e) {
            ba.setLastException(e);
             ba.raiseEventFromDifferentThread(XMLRPC.this.client, XMLRPC.this, 0,  XMLRPC.this.eventName + "_error", false, null);
         }
       }
     };
     BA.submitRunnable(runnable, this, 0);
  }
 

agraham

Expert
Licensed User
Longtime User
No, you haven't understood. This code is wrong

B4X:
....
XMLRPC1.initXMLRPCClient(sUrl)
stringCall(sService,sIn)
Log("Response XMLRPC: " & sOut)
....
Your Runnable most likely won't have executed when you do the Log and even if it had raiseEventFromDifferentThread() won't have completed as it runs on your main thread and so can't run until timer_tick() returns to the message loop. Like I said you need to handle it in the event.

B4X:
Sub xmlrpc1_success(valueAs String)
    sOut = value
    Log("Response XMLRPC: " & sOut)
End Sub
 

westingenieria

Active Member
Licensed User
Longtime User
Thank you! it works! now i can handle it in the event... but i think that im still using the main ui thread... when i call initXMLRPCClient(..) and stringCall(..) it stucks (for about 5 seconds (~)). Those functions are called in a timer and this timer is in a service. What do you think about this? any idea?
 

agraham

Expert
Licensed User
Longtime User
stringCall should post the Runnable and return immediately so I don't see how it can block.

I know nothing about initXMLRPCClient but as it has a URL parameter it looks like it might be a network operation and so might well block. In which case you need to do that asynchronously as well.
 
Top