You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中如何将Apollo异步回调封装为返回Intern对象的同步方法

Java中如何实现Apollo GraphQL异步调用的同步返回(类似async/await)?

我来帮你解决这个问题——你想要把Apollo的异步回调逻辑封装成能直接返回Intern对象的方法,类似async/await的效果对吧?在Java里确实没有像Kotlin或JavaScript那样原生的async/await语法,但有几种可行的方案可以实现你的需求,而且不需要提前创建对象再在回调里赋值:

方案1:用CompletableFuture包装异步回调,模拟await效果

Java 8及以上提供了CompletableFuture,可以把Apollo的回调式异步调用转换成Future,然后通过阻塞等待获取结果,这就类似async/await的效果了。

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

public InternQuery.Intern getIntern() throws ExecutionException, InterruptedException {
    CompletableFuture<InternQuery.Intern> resultFuture = new CompletableFuture<>();
    
    // 构建查询和ApolloCall
    InternQuery query = InternQuery.builder().build();
    ApolloCall<InternQuery.Data> apolloCall = new HoraApolloClient(this.context).getHoraApolloClient().query(query);
    
    apolloCall.enqueue(new ApolloCall.Callback<InternQuery.Data>() {
        @Override
        public void onResponse(@Nonnull Response<InternQuery.Data> response) {
            try {
                InternQuery.Data rData = response.data();
                // 这里保留你的错误处理逻辑
                if (rData == null || rData.intern() == null) {
                    resultFuture.completeExceptionally(new RuntimeException("Failed to get intern data"));
                    return;
                }
                resultFuture.complete(rData.intern());
            } catch (Exception e) {
                resultFuture.completeExceptionally(e);
            }
        }

        @Override
        public void onFailure(@Nonnull ApolloException e) {
            resultFuture.completeExceptionally(e);
        }
    });
    
    // 阻塞当前线程,直到Future完成,类似await
    return resultFuture.get();
}

注意事项:

  • 绝对不能在Android主线程调用这个方法!resultFuture.get()会阻塞线程,主线程被阻塞会直接导致ANR(应用无响应)。你需要在后台线程执行,比如用ExecutorService、AsyncTask或者Android Jetpack的Coroutine(Java可以借助kotlinx-coroutines-java库)。
  • 如果调用线程被中断,get()会抛出InterruptedException,需要处理或向上抛出。

方案2:直接使用Apollo的同步执行方法

其实Apollo客户端本身就提供了同步执行的execute()方法,不需要自己包装Future,直接就能同步获取响应结果,这是更简单的方式:

public InternQuery.Intern getIntern() throws ApolloException {
    // 构建查询和ApolloCall
    InternQuery query = InternQuery.builder().build();
    ApolloCall<InternQuery.Data> apolloCall = new HoraApolloClient(this.context).getHoraApolloClient().query(query);
    
    // 同步执行查询,直接获取响应
    Response<InternQuery.Data> response = apolloCall.execute();
    
    InternQuery.Data rData = response.data();
    // 保留你的错误处理逻辑
    if (rData == null || rData.intern() == null) {
        throw new RuntimeException("Failed to get intern data");
    }
    
    return rData.intern();
}

注意事项:

  • 和方案1一样,execute()是阻塞式方法,必须在后台线程执行,不能在主线程调用。
  • 执行过程中如果出现网络错误或GraphQL错误,会抛出ApolloException,需要捕获或向上抛出。

额外说明:避免阻塞的替代方案

如果你不想阻塞线程,但又希望代码逻辑更简洁,也可以考虑使用RxJava结合Apollo的Rx扩展(apollo-rxjava3),用响应式流的方式处理异步结果,但这种方式不是直接返回Intern对象,而是返回Observable<InternQuery.Intern>,需要订阅处理结果。不过这和你想要的“直接返回对象”的需求不太一致,所以优先推荐上面两种方案。

内容的提问来源于stack exchange,提问作者yerassyl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 09:04:11