【问题标题】:GMS IllegalStateException : Results have already been set?GMS IllegalStateException : 结果已经确定?
【发布时间】:2019-05-07 23:27:12
【问题描述】:

从上周开始,我们的应用程序出现了很多关于此的异常。我们使用 GMS 11.0.2

Fatal Exception: java.lang.IllegalStateException: Results have already been set
   at com.google.android.gms.common.internal.zzbo.zza(Unknown Source)
   at com.google.android.gms.internal.zzbbl.setResult(Unknown Source)
   at com.google.android.gms.internal.zzbbf.zzz(Unknown Source)
   at com.google.android.gms.internal.zzbbf.zzf(Unknown Source)
   at com.google.android.gms.internal.zzbbf.zzb(Unknown Source)
   at com.google.android.gms.internal.zzbav.zza(Unknown Source:3)
   at com.google.android.gms.internal.zzbdk.zzb(Unknown Source)
   at com.google.android.gms.internal.zzbdk.zzrR(Unknown Source)
   at com.google.android.gms.internal.zzbdk.onConnected(Unknown Source)
   at com.google.android.gms.common.internal.zzaa.onConnected(Unknown Source)
   at com.google.android.gms.common.internal.zzn.zzsR(Unknown Source:2)
   at com.google.android.gms.common.internal.zze.zzy(Unknown Source)
   at com.google.android.gms.common.internal.zzh.handleMessage(Unknown Source:4)
   at android.os.Handler.dispatchMessage(Handler.java:102)
   at android.os.Looper.loop(Looper.java:148)
   at android.os.HandlerThread.run(HandlerThread.java:61)

fabric 的日志报告。

我们使用firebase,gms版本是11.0.2

我们如何检查这些问题?

和gms 11.8.0版中同样的问题

java.lang.IllegalStateException: Results have already been set

   at com.google.android.gms.common.internal.zzbs.zza(Unknown Source)
   at com.google.android.gms.common.api.internal.zzs.setResult(Unknown Source)
   at com.google.android.gms.common.api.internal.zzm.zzy(Unknown Source)
   at com.google.android.gms.common.api.internal.zzm.zzf(Unknown Source)
   at com.google.android.gms.common.api.internal.zzm.zzb(Unknown Source)
   at com.google.android.gms.common.api.internal.zzc.zza(Unknown Source:3)
   at com.google.android.gms.common.api.internal.zzbr.zzb(Unknown Source)
   at com.google.android.gms.common.api.internal.zzbr.zzakz(Unknown Source)
   at com.google.android.gms.common.api.internal.zzbr.onConnected(Unknown Source)

【问题讨论】:

  • 尝试在您的代码中添加这一行:compile 'com.google.android.gms:play-services:11.0.4',正如文档中有关如何添加Add Google Play Services to Your Project 的说明。您也可以查看this post 以供进一步参考。
  • 问题解决了吗?
  • 你有任何更新的问题吗?我的应用也遇到了同样的问题(播放服务 11.6.2)。
  • 这里有一个错误报告:issuetracker.google.com/issues/70416429
  • 任何更新?看起来像谷歌播放服务中的错误。你设法重现它吗?我只能在 Crashlytics 中看到它

标签: android google-play-services illegalstateexception uncaughtexceptionhandler


【解决方案1】:

这个 hack 是基于 Jamin 和 divonas 的回答。它适用于 Crashlytics,但不适用 Crashlytics。在应用程序的 onCreate() 方法中调用此方法。如果您使用的是 Crashlytics,请在 Crashlytics 初始化后调用此方法。顺便说一句,ui 线程 id 可能并不总是 1。

/**
 * Hack for gms bug https://issuetracker.google.com/issues/70416429
 * https://stackoverflow.com/questions/47726111/gms-illegalstateexception-results-have-already-been-set
 */
private void handleGMS70416429() {
    final Thread.UncaughtExceptionHandler defaultExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
    final long uiThreadId = Thread.currentThread().getId();
    Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {

        @Override
        public void uncaughtException(Thread t, Throwable e) {
            if (e != null && t.getId() != uiThreadId && e.getStackTrace() != null && e.getStackTrace().length > 0
                    && e.getStackTrace()[0].toString().contains("com.google.android.gms")
                    && e.getMessage() != null && e.getMessage().contains("Results have already been set")) {
                return; // non-UI thread
            }
            if (defaultExceptionHandler != null)
                defaultExceptionHandler.uncaughtException(t, e);
        }

    });
}

【讨论】:

  • 您似乎没有在其他地方使用mDefaultExceptionHandlermUIThreadId:为什么需要它们作为私有成员变量?
  • @ozbek 可以使用 final 局部变量,我会更新答案,谢谢。
  • 我在 SafetyNet API 中遇到了这个问题。当我尝试调试时,我的代码没有执行您的建议。任何可能的原因,为什么?
【解决方案2】:

由于bug还没有修复,在BaseApplication的onCreate()方法中调用handleGMSException()或者实现自己的ExceptionHandler。此 hack 是基于 Jamin 的回答,并根据 Hexise 的评论进行了更新。

private void handleGMSException() {
    Thread.UncaughtExceptionHandler rootHandler = Thread.getDefaultUncaughtExceptionHandler();
    Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> {
        if (!isGMSException(thread, throwable)) {
            rootHandler.uncaughtException(thread, throwable);
        }
    });
}

private boolean isGMSException(Thread thread, Throwable throwable) {
    //Check if Main Thread.
    if (throwable == null || thread.getId() == 1) return false;

    if (throwable.getStackTrace() != null && throwable.getStackTrace().length > 0
            && throwable.getStackTrace()[0].toString().contains("com.google.android.gms")
            && throwable.getMessage().contains("Results have already been set")) {
        return true;
    }

    return false;
}

【讨论】:

  • 会进入死循环吗?由于 DefaultUncaughtExceptionHandler 已经改成自定义的,Thread.getDefaultUncaughtExceptionHandler().uncaughtException() 会调用自己的方法。
  • 我在 SafetyNet API 中遇到了这个问题。当我尝试调试时,我的代码没有执行您的建议。任何可能的原因,为什么?
【解决方案3】:

这个bug我没有解决,但是我尝试通过UncaughtExceptionHandler来捕捉它。我使用的是fabric,所以我在fabric之后注册了MyUncaughtExceptionHandler,这样我就可以确定是否先处理这个问题。如果我发现是这个例外。我会抓住它。

//try to catch some uncaught exception
 public static boolean crashInterceptor(Thread thread, Throwable throwable) {

if (throwable == null || thread.getId() == 1) {
  //Don't intercept the Exception of Main Thread.
  return false;
}

String classpath = null;
if (throwable.getStackTrace() != null && throwable.getStackTrace().length > 0) {
  classpath = throwable.getStackTrace()[0].toString();
}

//intercept GMS Exception
if (classpath != null
    && throwable.getMessage().contains("Results have already been set")
    && classpath.contains("com.google.android.gms")) {
  //CrashHelper.logNonFatalException();
  return true;
}

return false;
}
}

【讨论】:

    猜你喜欢
    • 2015-02-18
    • 1970-01-01
    • 2011-10-29
    • 1970-01-01
    • 2015-02-24
    • 1970-01-01
    • 1970-01-01
    • 2016-04-16
    • 1970-01-01
    相关资源
    最近更新 更多