Search code examples
androidcompletable-future

Read value returned in CompletableFuture


A function from some SDK is returning me a CompletableFuture. How can I read the value properly once it's reached.

My Code:

CompletableFuture<Web3ClientVersion> web3clientCompletableFuture;
web3clientCompletableFuture = web3jNode.web3ClientVersion().sendAsync();

sendAsync() Code (In SDK):

public CompletableFuture<T> sendAsync() {
    return  web3jService.sendAsync(this, responseType);
}

I can access the returned data using get(), but that would make the whole process syncronus and block UI.

I've checked the functions signatures on Android API Reference, like:

thenApply(Function<? super T, ? extends U> fn) 
handle(BiFunction<? super T, Throwable, ? extends U> fn) 

But seems I require some code examples.

[Note: I'm not so familiar with lambda]


Solution

  • Here is a tutorial that has examples that show you how to use these powerful methods of CompletableFuture. You are right you want to use thenApply() if you have to return value after you process the future. But if you simply want to process the future and not return anything, you should use thenAccept() and thenRun(). There are other methods listed with examples as well.

    Here is an example that simply returns a CompletableFuture of type integer:

    CompletableFuture<Integer> mynumber = null;
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
                mynumber = CompletableFuture.supplyAsync(() -> {
                    try {
                        TimeUnit.SECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        throw new IllegalStateException(e);
                    }
                    return 4 * 4;
                });
            }
    

    Here arg is the result(CompletableFuture) from the above step, and in your case the data you are receiving from the SDK. You are attaching a callback method(thenApply()) and do what ever you would like to do with it. Depending on your implementation, you can attach multiple thenApply(). Here I am calling a method that will take the result and do some computation with it.

            CompletableFuture<Integer> willdoStuff = null;
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
                willdoStuff = mynumber.thenApply(arg -> {
                    compute(arg);
                    return arg / 2;
                });
            }
    
    public void compute(int someInt){
            Toast.makeText(getApplicationContext(), "The result of the computation is" + someInt, Toast.LENGTH_LONG).show();
    }
    

    Just comment out the sleep code to execute this code in the main thread. The Lambda function is simply input and output, the arguments before {} being the input and the statement within the {}, which is actually a function that does something with the arguments(input). You might want to ask different question in regards to that.