Task API:如何将异步调用重构为同步调用并捕获ApiException
解决方案:从ExecutionException中提取ApiException
你遇到的问题其实是因为Tasks.await()会把Task执行过程中抛出的ApiException包装在ExecutionException里面,所以直接catch是拿不到的。要像异步调用那样精准捕获ApiException,你可以这么做:
完整的同步实现代码
Task<GoogleSignInAccount> task = googleSignInClient.silentSignIn(); try { GoogleSignInAccount googleSignInAccount = Tasks.await(task); // 成功获取账号后的业务逻辑 } catch (InterruptedException e) { // 处理中断异常,最佳实践是恢复线程中断状态 Thread.currentThread().interrupt(); e.printStackTrace(); } catch (ExecutionException e) { // 从包装异常中取出真正的执行异常 Throwable cause = e.getCause(); if (cause instanceof ApiException) { ApiException apiException = (ApiException) cause; // 这里就可以完全复用你异步代码里的ApiException处理逻辑了 if (apiException.getStatusCode() == GoogleSignInStatusCodes.SIGN_IN_REQUIRED) { // 处理需要用户重新登录的场景 } // 其他登录状态码的处理逻辑也可以放在这里 } else { // 处理非ApiException类型的异常 e.printStackTrace(); } }
关键逻辑说明
- 异常包装的本质:
Tasks.await()会把Task执行时抛出的具体异常(比如ApiException)统一包装成ExecutionException抛出,所以必须从ExecutionException的cause属性里才能拿到真正的异常。 - 类型安全判断:用
instanceof先判断cause是不是ApiException实例,避免强制类型转换出错。 - 复用原有逻辑:转换完成后,你就可以和异步调用时一样,通过
getStatusCode()来处理不同的登录状态了。
这样就能完美实现和异步调用一致的ApiException捕获逻辑啦~
内容的提问来源于stack exchange,提问作者Cheok Yan Cheng
相关产品推荐
相关产品推荐

