private synchronized static void startBackgroundThread () {
        if (backgroundThread == null) {
            backgroundThreadMayRun = true;
            backgroundThread = new Thread(asyncThreadGroup, "AnalyticsBackgroundThread") {
                @Override
                public void run () {
                    Logger.logInfo("AnalyticsBackgroundThread started");
                    while (backgroundThreadMayRun) {
                        try {
                            String url = null;
                            synchronized (fifo) {
                                if (fifo.isEmpty()) {
                                    fifo.wait();
                                }
                                if (!fifo.isEmpty()) {
                                    // Get a reference to the oldest element in the FIFO, but leave it in the FIFO until it is processed.
                                    url = fifo.getFirst();
                                }
                            }
                            if (url != null) {
                                try {
                                    dispatchRequest(url);
                                } finally {
                                    // Now that we have completed the HTTP request to GA, remove the element from the FIFO.
                                    synchronized (fifo) {
                                        fifo.removeFirst();
                                    }
                                }
                            }
                        } catch (Exception e) {
                            Logger.logError("Got exception from dispatch thread", e);
                        }
                    }
                }
            };
            backgroundThread.setDaemon(true);
            backgroundThread.start();
        }
    }