Skip to content

5.1 Async Tasks and Callbacks

All operations in this library - like updating the screen or getting information about the scanner - are executed asynchronously.

The idea is to use Tasks. The result of the Task can be further processed once it is available. Within an async Task, other operations can be awaited for.

On the main thread, Tasks are not allowed (because it would block the UI), which means you need to register for the onComplete, onSuccess or onError callback.

Please be aware that Task relies on Kotlin Coroutines and therefore cannot be used for real blocking code.

class MainActivity: Activity(), NIMMSTAEventHandler {
    /* ... */


    fun asyncTask() = Task {
        veryLongRunningOperation().await() // Wait for the Task result, which means it is blocking the current Task.
    }

    fun mainThread() = runOnUiThread {
        asyncTask().await() // Illegal because the UI Thread should not be blocked. Will throw RuntimeException.

        asyncTask().onComplete { task ->
            // Correct since we handle on the main thread and do not block it
            try {
                task.result // Throws exception if the task throws an exception
            } catch(t: Throwable) {
                // Exception handling
            }
        }
    }

    // You can also add types to tasks
    fun asyncTaskIntResult() = Task<Int> {
        delay(100) // wait 100ms

        return 1
    }

    /* ... */
}
class MainActivity extends Activity implements NIMMSTAEventHandler {
    /* ... */

    private Task<Unit> asyncTask() throws Throwable {
        return new Task<Unit>(new TaskCallback<Unit>() {
            @Override
            public Unit run(Task task) throws Exception {
               try {
                    return veryLongRunningOperation().await(); // Wait for the Task result, which means it is blocking the current Task.
                } catch (Throwable throwable) {
                    throwable.printStackTrace();
                }
                return null;
            }
        });
    }

    private void mainThread() {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                try {
                    asyncTask().await(); // Illegal because the UI Thread should not be blocked. Will throw RuntimeException.
                } catch (Throwable throwable) {
                    throwable.printStackTrace();
                }
            }

            public void run() {
                asyncTask().onComplete(new NIMMSTADoneCallback<Task<Unit>>() {
                    @Override
                    public void onDone(Task<Unit> result) {
                        try {
                            result.getResult(); // Throws exception if the task throws an exception
                        } catch (Throwable throwable) {
                            throwable.printStackTrace(); // Exception handling
                        }
                    }
                });
            }
        });
    }

    // You can also add types to Tasks:
    private Task<Integer> asyncTaskIntResult() {
        new Task<Integer>(new TaskCallback<Integer>() {
            @Override
            public Integer run(Task task) throws Exception {
                return 1;
            }
        });
        return null;
    }

    /* ... */
}