Source code

Revision control

Copy as Markdown

Other Tools

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.util;
import android.os.Handler;
import android.os.Looper;
final class GeckoBackgroundThread extends Thread {
private static final String LOOPER_NAME = "GeckoBackgroundThread";
// Guarded by 'GeckoBackgroundThread.class'.
private static Handler handler;
private static Thread thread;
// The initial Runnable to run on the new thread. Its purpose
// is to avoid us having to wait for the new thread to start.
private Runnable mInitialRunnable;
// Singleton, so private constructor.
private GeckoBackgroundThread(final Runnable initialRunnable) {
mInitialRunnable = initialRunnable;
}
@Override
public void run() {
setName(LOOPER_NAME);
Looper.prepare();
synchronized (GeckoBackgroundThread.class) {
handler = new Handler();
GeckoBackgroundThread.class.notifyAll();
}
if (mInitialRunnable != null) {
mInitialRunnable.run();
mInitialRunnable = null;
}
Looper.loop();
}
private static void startThread(final Runnable initialRunnable) {
thread = new GeckoBackgroundThread(initialRunnable);
thread.setDaemon(true);
thread.start();
}
// Get a Handler for a looper thread, or create one if it doesn't yet exist.
/*package*/ static synchronized Handler getHandler() {
if (thread == null) {
startThread(null);
}
while (handler == null) {
try {
GeckoBackgroundThread.class.wait();
} catch (final InterruptedException e) {
}
}
return handler;
}
/*package*/ static synchronized void post(final Runnable runnable) {
if (thread == null) {
startThread(runnable);
return;
}
getHandler().post(runnable);
}
}