Java Question Best approach - PendingResult or Blocking Thread

barx

Well-Known Member
Licensed User
Longtime User
Hi,

As part of this Wearable DataLayer library I'm creating there are a few bits that require you to 'wait' for a result. A key example is getting the Connected Nodes (Devices).

The NodeApi has a method getConnectedNodes, but the result isn't instant as it needs to search the nodes. There are 2 options for working with this.

Option 1 - Pending result
example:
B4X:
PendingResult<NodeApi.GetConnectedNodesResult> nodes = Wearable.NodeApi.getConnectedNodes(googleApiClient);
            nodes.setResultCallback(new ResultCallback<NodeApi.GetConnectedNodesResult>() {
                @Override
                public void onResult(NodeApi.GetConnectedNodesResult result) {
......//code overwriting Callbacks)

Option 2 - Blocking thread (New runnable)
example:
B4X:
    new Thread(new Runnable() {
        @Override
        public void run() {
            client.blockingConnect(CONNECTION_TIME_OUT_MS, TimeUnit.MILLISECONDS);
            NodeApi.GetConnectedNodesResult result =
                    Wearable.NodeApi.getConnectedNodes(client).await();
            List<Node> nodes = result.getNodes();
            if (nodes.size() > 0) {
                nodeId = nodes.get(0).getId();
            }
            client.disconnect();
        }
    }).start();

Note these are online examples not the actual code I will use. Now I cannot figure which would be best here. Obviously the best way would be for b4a user to call

B4X:
Dim NodeList as List = DataLAyer1.GetNodes

My understanding of option1 is that I would have to raise another event with the results. So, Would option 2 allow the above technique?

Thanks
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
You should never block the main thread.

Your code should manage the long task in the background and then raise an event when the task completes.

For example this code creates a Runnable and sends it to the internal thread pool. When the task is complete it raises an event:
B4X:
public void Sync(final BA ba) {
     ba.submitRunnable(new Runnable() {

       @Override
       public void run() {
         boolean success = true;
         try {
           fileSystem.syncNowAndWait();
         } catch (DbxException e) {
           BA.printException(e, true);
           success = false;

         }
         ba.raiseEventFromDifferentThread(null, null, 0, eventName + "_synccompleted", false, new Object[] {success});
       }

     }, null, 0);
   }
 

barx

Well-Known Member
Licensed User
Longtime User
Hi @Erel, thanks for the reply.

So your example is very similar to the second exampl of mine above. It uses blockingConnect but it is run in a new thread so as to not block the main thread as you say. The first example uses a PendingResult so is processed in a background thread too. On that theory, both run in another thread and both have to raise an event for the result. So, technically there isn't any difference between the 2 other that the code written. Or am I misunderstanding it? That's why I was getting confused as both seem to do the same thing. Either way< I will need to call an event with the results..
 
Top