GoogleApiClient:多线程Android应用中的“结果已被消耗”

时间:2015-12-15 06:01:32

标签: android multithreading google-play-services google-signin

处理

的最佳方法是什么
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);

同时,活动启动一个IntentService(刷新GCM令牌),它也构建一个新的GoogleApiClient实例,然后调用

OptionalPendingResult<GoogleSignInResult> opr = 
    GoogleSignInApi.silentSignIn(googleApiClient);
opr.await(); // Blocks
return opr.get();

opr.get()电话会发生异常。似乎GoogleApiClient在某处共享其资源,并且创建它的新实例并不能减轻我对某些跨线程状态的管理。

您需要两次使用GoogleApiClient的方法是什么?

保持ApiClient的静态持有者? 保持一个共享的原子参考,如“我们正在连接,请保持”? 有一些关于GoogleApiClient的包装?

更新

MainActivity需要GoogleApiClient来确保用户已登录,如果没有则显示提示。

对于OAuth令牌,IntentService实际上只需要GoogleSignInAccount。但为了确保令牌仍然新鲜,它会使用GoogleApiClient获得一个新帐号。因此,将GoogleSignInAccount存储在某些共享存储中也会有所帮助。但我怎么知道它是否仍然新鲜呢?

1 个答案:

答案 0 :(得分:1)

实际上,opr.await()已经消耗了资源并将其返回。应该是

OptionalPendingResult<GoogleSignInResult> opr = 
    GoogleSignInApi.silentSignIn(googleApiClient);
return opr.await(); // Blocks