简体   繁体   中英

GMS IllegalStateException : Results have already been set?

From last week , Our app occur a lot of exception about this .we use 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)

the log report by fabric.

we use firebase and gms version is 11.0.2

how do we check these problems?

and the same problem in gms version 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)

This hack is based on Jamin's and divonas' answer. It works with Crashlytics and without Crashlytics. Call this method in Application onCreate() method. If you are using Crashlytics, call this method after Crashlytics initialized. BTW, ui thread id may not always be 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);
        }

    });
}

Since the bug hasn't been fixed yet, call handleGMSException() in BaseApplication's onCreate() method or implement your own ExceptionHandler. This hack is based on Jamin's answer, updated on Hexise's comment.

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;
}

I haven't solved this bug, but I try to catch it by UncaughtExceptionHandler .I'm using fabric, so I register MyUncaughtExceptionHandler after fabric so that I can determine whether handle this problem first. if I find is this exception. I will catch it.

//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;
}
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM