michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this file, michael@0: * You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: package org.mozilla.gecko.util; michael@0: michael@0: import android.os.Handler; michael@0: import android.os.Looper; michael@0: michael@0: import java.util.concurrent.SynchronousQueue; michael@0: michael@0: final class GeckoBackgroundThread extends Thread { michael@0: private static final String LOOPER_NAME = "GeckoBackgroundThread"; michael@0: michael@0: // Guarded by 'this'. michael@0: private static Handler sHandler = null; michael@0: private SynchronousQueue mHandlerQueue = new SynchronousQueue(); michael@0: michael@0: // Singleton, so private constructor. michael@0: private GeckoBackgroundThread() { michael@0: super(); michael@0: } michael@0: michael@0: @Override michael@0: public void run() { michael@0: setName(LOOPER_NAME); michael@0: Looper.prepare(); michael@0: try { michael@0: mHandlerQueue.put(new Handler()); michael@0: } catch (InterruptedException ie) {} michael@0: michael@0: Looper.loop(); michael@0: } michael@0: michael@0: // Get a Handler for a looper thread, or create one if it doesn't yet exist. michael@0: /*package*/ static synchronized Handler getHandler() { michael@0: if (sHandler == null) { michael@0: GeckoBackgroundThread lt = new GeckoBackgroundThread(); michael@0: ThreadUtils.setBackgroundThread(lt); michael@0: lt.start(); michael@0: try { michael@0: sHandler = lt.mHandlerQueue.take(); michael@0: } catch (InterruptedException ie) {} michael@0: } michael@0: return sHandler; michael@0: } michael@0: michael@0: /*package*/ static void post(Runnable runnable) { michael@0: Handler handler = getHandler(); michael@0: if (handler == null) { michael@0: throw new IllegalStateException("No handler! Must have been interrupted. Not posting."); michael@0: } michael@0: handler.post(runnable); michael@0: } michael@0: }