am 731b8996: Merge "Run with scissors." into jb-mr1-dev
* commit '731b8996eaa7e45b206273d4691506069229449a': Run with scissors.
This commit is contained in:
@@ -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.
|
||||
*/
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user