Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - synchronous callback

I have the following code which is executed asynchronously. I would like to make it synchronous in order to follow some logical flow but I cannot work out how.

You will see that scanning is set to true to indicate that the method is still working, at the beginning - I then initiate a findPrinters(...) command - this contains a DiscoveryHandler which runs asynchronously - foundPrinter() is called each time an item is discovered. discoveryFinished() is when the discovery process is successfully completed, and discoveryError(...) is called whenever an error occurs.

I rely on something being set in my DiscoveryHandler before I would like to return from this method. Hence why I have while (scanning) underneath it. But this feels like a hack to me, and not the correct way of doing things. I cannot get wait() and notify() working. Can someone tell me what the correct way to do this is please?

private boolean findPrinter(final Context ctx) {
    try {
        scanning = true;
        BluetoothDiscoverer.findPrinters(ctx, new DiscoveryHandler() {

            public void foundPrinter(DiscoveredPrinter device) {
                if (device instanceof DiscoveredPrinterBluetooth) {
                    DiscoveredPrinterBluetooth btDevice = (DiscoveredPrinterBluetooth) device;

                    if (btDevice.friendlyName.startsWith("XXXX")) {
                        try {
                            connection = new BluetoothConnection(btDevice.address);
                            connection.open();

                            if (connection.isConnected()) {
                                address = btDevice.address;
                            }
                        } catch (Exception ex) {

                        }
                    }
                }
            }

            public void discoveryFinished() {
                scanning = false;
            }

            public void discoveryError(String arg0) {
                scanning = false;
            }
        });
    } catch (Exception ex) {

    }

    while (scanning) {}

    return false;
}
like image 757
keldar Avatar asked Dec 18 '13 13:12

keldar


People also ask

Can callback be synchronous?

There are 2 kinds of callback functions: synchronous and asynchronous. The synchronous callbacks are executed at the same time as the higher-order function that uses the callback. Synchronous callbacks are blocking.

What is the difference between a synchronous callback and an asynchronous callback?

The main difference between synchronous and asynchronous callbacks is that synchronous callbacks are executed immediately, whereas the execution of asynchronous callbacks is deferred to a later point in time.

What is synchronized and Asynchronized in Java?

Synchronous (Sync) and asynchronous (Async) programming can be done in one or multiple threads. The main difference between the two is when using synchronous programming we can execute one task at a time, but when using asynchronous programming we can execute multiple tasks at the same time.

Can a callback be async?

Asynchronous callbacks are functions passed to another function that starts executing code in the background. Typically, when the code in the background finishes, the async callback function is called as a way of notifying and passing on data to the callback function that the background task is finished.


1 Answers

You could do this with CountDownLatch, which might be the lightest synchronization primitive in java.util.concurrent:

private boolean findPrinter(final Context ctx) {
    final CountDownLatch latch = new CountDownLatch(1);
    final boolean[] result = {false};

    ...

    BluetoothDiscoverer.findPrinters(ctx, new DiscoveryHandler() {

        ...

        public void discoveryFinished() {
            result[0] = true;
            latch.countDown();
        }
    
        public void discoveryError(String arg0) {
            result[0] = false;
            latch.countDown();
        }

        ...
    }

    // before final return
    // wait for 10 seconds for the response
    latch.await(10, TimeUnit.SECONDS);

    //return the result, it will return false when there is timeout
    return result[0];
}
like image 197
Andrey Chaschev Avatar answered Sep 18 '22 13:09

Andrey Chaschev