GoogleApiClient:多线程Android应用程序中的“结果已被使用”
Posted
技术标签:
【中文标题】GoogleApiClient:多线程Android应用程序中的“结果已被使用”【英文标题】:GoogleApiClient: "Result has already been consumed" in multi-thread Android app 【发布时间】:2016-03-20 19:47:10 【问题描述】:最好的处理方法是什么
java.lang.IllegalStateException: Result has already been consumed.
at com.google.android.gms.common.internal.zzx.zza(Unknown Source)
at com.google.android.gms.internal.zzly.await(Unknown Source)
at com.google.android.gms.internal.zzmo.await(Unknown Source)
at com.google.android.gms.internal.zzmo.get(Unknown Source)
当使用来自不同线程的两个不同 GoogleApiClients 时会发生什么情况?
我有一个 MainActivity,onStart() 构建一个新的 GoogleApiClient 实例,然后调用
OptionalPendingResult<GoogleSignInResult> opr =
GoogleSignInApi.silentSignIn(googleApiClient);
opr.setResultCallback(myCallback);
同时,Activity 启动了一个 IntentService(用于刷新 GCM 令牌),它也构建了一个新的 GoogleApiClient 实例,并调用
OptionalPendingResult<GoogleSignInResult> opr =
GoogleSignInApi.silentSignIn(googleApiClient);
opr.await(); // Blocks
return opr.get();
异常发生在opr.get()
调用上。似乎 GoogleApiClient 在某处共享它的资源,并且创建它的新实例并不能让我从管理一些跨线程状态中解脱出来。
当您需要两次时,您使用 GoogleApiClient 的方法是什么?
保持 ApiClient 的静态持有者? 保持共享的原子引用,例如“我们现在正在连接,请保持”? 对 GoogleApiClient 有一些包装?
更新
MainActivity 需要 GoogleApiClient 来确保用户已登录,如果未登录则显示提示。
IntentService 实际上只需要 GoogleSignInAccount 来获取 OAuth 令牌。但是为了确保令牌仍然是新鲜的,它使用 GoogleApiClient 获取一个新鲜的帐户。因此,也许将 GoogleSignInAccount 存储在某个共享商店中也会有所帮助。但是我怎么知道它是否还新鲜呢?
【问题讨论】:
两个GoogleApiClient-s几乎相同,不同的是Activity有enableAutoManage(this, this)
,而IntentService自己调用connect()/disconnect()。
【参考方案1】:
其实opr.await()
已经消耗资源并返回。应该是
OptionalPendingResult<GoogleSignInResult> opr =
GoogleSignInApi.silentSignIn(googleApiClient);
return opr.await(); // Blocks
【讨论】:
以上是关于GoogleApiClient:多线程Android应用程序中的“结果已被使用”的主要内容,如果未能解决你的问题,请参考以下文章
GoogleApiClient 在调用 onConnected 函数后抛出“GoogleApiClient 尚未连接”
GoogleApiClient.isConnected() 在飞行模式下返回 true