Loading core/java/android/os/Handler.java +81 −0 Original line number Diff line number Diff line Loading @@ -411,6 +411,50 @@ public class Handler { return sendMessageAtFrontOfQueue(getPostMessage(r)); } /** * Runs the specified task synchronously. * * If the current thread is the same as the handler thread, then the runnable * runs immediately without being enqueued. Otherwise, posts the runnable * to the handler and waits for it to complete before returning. * * This method is dangerous! Improper use can result in deadlocks. * Never call this method while any locks are held or use it in a * possibly re-entrant manner. * * This method is occasionally useful in situations where a background thread * must synchronously await completion of a task that must run on the * handler's thread. However, this problem is often a symptom of bad design. * Consider improving the design (if possible) before resorting to this method. * * One example of where you might want to use this method is when you just * set up a Handler thread and need to perform some initialization steps on * it before continuing execution. * * @param r The Runnable that will be executed synchronously. * * @return Returns true if the Runnable was successfully executed. * Returns false on failure, usually because the * looper processing the message queue is exiting. * * @hide This method is prone to abuse and should probably not be in the API. * If we ever do make it part of the API, we might want to rename it to something * less funny like runUnsafe(). */ public final boolean runWithScissors(final Runnable r) { if (r == null) { throw new IllegalArgumentException("runnable must not be null"); } if (Looper.myLooper() == mLooper) { r.run(); return true; } BlockingRunnable br = new BlockingRunnable(r); return br.postAndWait(this); } /** * Remove any pending posts of Runnable r that are in the message queue. */ Loading Loading @@ -678,4 +722,41 @@ public class Handler { final Callback mCallback; final boolean mAsynchronous; IMessenger mMessenger; private static final class BlockingRunnable implements Runnable { private final Runnable mTask; private boolean mDone; public BlockingRunnable(Runnable task) { mTask = task; } @Override public void run() { try { mTask.run(); } finally { synchronized (this) { mDone = true; notifyAll(); } } } public boolean postAndWait(Handler handler) { if (!handler.post(this)) { return false; } synchronized (this) { while (!mDone) { try { wait(); } catch (InterruptedException ex) { } } } return true; } } } Loading
core/java/android/os/Handler.java +81 −0 Original line number Diff line number Diff line Loading @@ -411,6 +411,50 @@ public class Handler { return sendMessageAtFrontOfQueue(getPostMessage(r)); } /** * Runs the specified task synchronously. * * If the current thread is the same as the handler thread, then the runnable * runs immediately without being enqueued. Otherwise, posts the runnable * to the handler and waits for it to complete before returning. * * This method is dangerous! Improper use can result in deadlocks. * Never call this method while any locks are held or use it in a * possibly re-entrant manner. * * This method is occasionally useful in situations where a background thread * must synchronously await completion of a task that must run on the * handler's thread. However, this problem is often a symptom of bad design. * Consider improving the design (if possible) before resorting to this method. * * One example of where you might want to use this method is when you just * set up a Handler thread and need to perform some initialization steps on * it before continuing execution. * * @param r The Runnable that will be executed synchronously. * * @return Returns true if the Runnable was successfully executed. * Returns false on failure, usually because the * looper processing the message queue is exiting. * * @hide This method is prone to abuse and should probably not be in the API. * If we ever do make it part of the API, we might want to rename it to something * less funny like runUnsafe(). */ public final boolean runWithScissors(final Runnable r) { if (r == null) { throw new IllegalArgumentException("runnable must not be null"); } if (Looper.myLooper() == mLooper) { r.run(); return true; } BlockingRunnable br = new BlockingRunnable(r); return br.postAndWait(this); } /** * Remove any pending posts of Runnable r that are in the message queue. */ Loading Loading @@ -678,4 +722,41 @@ public class Handler { final Callback mCallback; final boolean mAsynchronous; IMessenger mMessenger; private static final class BlockingRunnable implements Runnable { private final Runnable mTask; private boolean mDone; public BlockingRunnable(Runnable task) { mTask = task; } @Override public void run() { try { mTask.run(); } finally { synchronized (this) { mDone = true; notifyAll(); } } } public boolean postAndWait(Handler handler) { if (!handler.post(this)) { return false; } synchronized (this) { while (!mDone) { try { wait(); } catch (InterruptedException ex) { } } } return true; } } }