Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid TagManager "IllegalStateException: Results have already been set"

I have recently introduced Google TagManager into my Android app in order to push changes to app config without needing to redeploy the app.

But I am getting instances of:

java.lang.IllegalStateException: Results have already been set
at com.google.android.gms.common.internal.p.a(Unknown Source)
at com.google.android.gms.common.api.b$a.a(Unknown Source)
at com.google.android.gms.tagmanager.ed.a(Unknown Source)
at com.google.android.gms.tagmanager.ed.a(Unknown Source)
at com.google.android.gms.tagmanager.ed$b.a(Unknown Source)
at com.google.android.gms.tagmanager.ed$b.a(Unknown Source)
at com.google.android.gms.tagmanager.cj.c(Unknown Source)
at com.google.android.gms.tagmanager.ck.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)

They occur across a variety of devices from Android 4.4 to 5.0.1

As you can see there is no element of my app in the stacktrace, and I am really at a loss and to what I can do (other than remove TagManager) to avoid or mitigate the error.

I have found one reference to the same error message associated with GooglePlus login so I am thinking it might be to do with the Google Play Services library.

Anyone else seen it? Any ideas?

Have raised issue with Play-Games project: https://code.google.com/p/play-games-platform/issues/detail?id=209

like image 459
William Avatar asked Dec 19 '14 22:12

William


1 Answers

This is an internal bug due to a race condition within TagManager and should be fixed in Google Play Services 6.7 (February 17, 2015).

See https://productforums.google.com/forum/?utm_medium=email&utm_source=footer#!msg/tag-manager/NOlng117_2g/w46OkQS5Gm8J and also https://developers.google.com/analytics/devguides/collection/android/changelog

In the mean time you can work around it by:

private static class MyHandler implements Thread.UncaughtExceptionHandler {

    private final Thread.UncaughtExceptionHandler defaultHandler;

    MyHandler(Thread.UncaughtExceptionHandler defaultHandler) {
        this.defaultHandler = defaultHandler;
    }

    @Override
    public void uncaughtException(Thread thread, Throwable ex) {
        String classpath = null;
        if (ex != null && ex.getStackTrace().length > 0) {
            classpath = ex.getStackTrace()[0].toString();
        }
        if (classpath != null && 
            ex.getMessage().contains("Results have already been set") && 
            classpath.contains("com.google.android.gms.tagmanager") ) {
            // ignore
         } else {
           // run your default handler
           defaultHandler.uncaughtException(thread, ex);
       }
    }
};

// Application#onCreate
public void onCreate() {
    // for catching app global unhandled exceptions
    final Thread.UncaughtExceptionHandler defaultHandler = Thread.getDefaultUncaughtExceptionHandler();
    Thread.setDefaultUncaughtExceptionHandler(new MyHandler(defaultHandler));
}
like image 112
William Avatar answered Nov 14 '22 14:11

William