OKHttp DNS 异步查找

OKHttp DNS lookup asynchronously

public class OkHttpDns implements Dns {
    @NotNull
    @Override
    public List<InetAddress> lookup(@NotNull String hostname) throws UnknownHostException {
        MyLookUpUtility.getInstance.lookup(hostname, new MyLookUpUtility.lookupCallback() 
        {
            @Override
            public void onlookupResponseSuccess(JSONObject nslookupResponseJSON) {
                Log.d("LookupResponse", nslookupResponseJSON.toString());
            }

            @Override
            public void onlookupResponseFailure(String errCode) {
                Log.d("LookupResponse", "Error Code : "+errCode);
            }
        });
    }
}

以上代码中,OKHttp的DNS接口查找方法要return立即执行。但是我的自定义 NSLookupUtility 是一个异步调用,我只会在一段时间后获得主机名的 ip 地址。如何解决这个问题呢?如何使同步调用等待其中的异步调用?

看看CompletableFuture。您将在 lookup() 中创建一个实例,启动异步查找,然后调用 future.get()。异步调用完成后,调用 future.complete().

    @Override
    public List<InetAddress> lookup(@NotNull String hostName) throws UnknownHostException {

        completableFuture = new CompletableFuture<>();
        performLookUp(hostName);
        try {
            String ipAddress = completableFuture.get();
            if (ipAddress != null) {
                List<InetAddress> inetAddresses = Arrays.asList(InetAddress.getAllByName(ipAddress));
                return inetAddresses;
            }
        } catch (ExecutionException e) {
            Log.d(TAG, "Error : ExecutionException : "+e );
            e.printStackTrace();
        } catch (InterruptedException e) {
            Log.d(TAG, "Error : InterruptedException : "+e );
            e.printStackTrace();
        }

        return Dns.SYSTEM.lookup(hostName);
    }

    private void performLookUp(@NotNull String hostName) {
       MyUtiluty.getInstance().lookup(hostName,
                 new MyCallBack() {

                    @Override
                    public void onSuccess(String ip) {
                            completableFuture.complete(ip);
                    }

                    @Override
                    public void onFailure(String errCode) {
                        completableFuture.complete(null);
                    }
                });
    }