如果这个方法不是在运行Activity的主线程UiThread上被调用的,也就是在子线程上调用的,那么把action提交到主线程的Main Looper消息队列中排队然后返回
如果这个方法是在运行Activity的主线程UiThread上被调用的,那么不需要进入Main Looper队列排队,直接调用执行
你看,这多偏心,正室就是权力大,二房就是差点,特别是二房比较多的时候,你慢慢排吧。不过我们的Main Looper还算好了,在我们现实中更多是反过来了,搞了个二房三房后把正室给休掉了。这里就不往外扯了,这里我们主要关心子线程的情况,既然是把action提交到Main Looper进行排队,那么必然是异步的了,否则消息队列的存在就没有意思了,所以这里我们要在脑袋总记得runOnUiThread是异步的。我们再看Instrumentation的runOnMainSync方法:
/* */ public void runOnMainSync(Runnable runner)
/* */ {
/* 344 */ validateNotAppThread();
/* 345 */ SyncRunnable sr = new SyncRunnable(runner);
/* 346 */ this.mThread.getHandler().post(sr);
/* 347 */ sr.waitForComplete();
/* */ }这里也是从再从主线程获得Main Looper的Handler后往Main Looper消息队列中提交action,但人家提交完之后还会等待该action线程的执行完毕才会退出这个函数,所以两个方法的区别就是:Activity的runOnUiThread是异步执行的,Instrumentation的runOnMainSync是同步执行的。runOnMainSync又是怎么实现这一点的呢?这个我们就要看Instrumetnation的内部类SyncRunnable了:/* */ private static final class SyncRunnable implements Runnable {
/* */ private final Runnable mTarget;
/* */ private boolean mComplete;
/* */
/* 1715 */ public SyncRunnable(Runnable target) { this.mTarget = target; }
/* */
/* */ public void run()
/* */ {
/* 1719 */ this.mTarget.run();
/* 1720 */ synchronized (this) {
/* 1721 */ this.mComplete = true;
/* 1722 */ notifyAll();
/* */ }
/* */ }
/* */
/* */ public void waitForComplete() {
/* 1727 */ synchronized (this) {
/* 1728 */ while (!this.mComplete) {
/* */ try {
/* 1730 */ wait();
/* */ }
/* */ catch (InterruptedException e) {}
/* */ }
/* */ }
/* */ }
/* */ }它也是从runnable线程类继承下来的。在run方法的1720到1722行我们可以看到,该运行在Main UiThread的方法在跑完后会把Instrumentation实例的mComplete变量设置成true,而runOnMainSync最后调用的运行在子线程中的waitForComplete方一直等待这个mComplete变量变成true才会返回,也就是说一直等待主线程的调用完成才会返回,那么到了这里就很清楚runOnMainSync是如何通过SyncRunnable这个内部类实现同步的了。这里还有必要提一提的是runOnMainSync方法调用的第一个函数validateNotAppThread,其实它做的事情就是去查看下当前线程的Looper是不是主线程的Main Looper,如果是的话就直接抛出异常,代表runOnMainSynce这个方法是不应该在主线程调用的;如果不是的话就什么都不干继续往下跑。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/ruanjian/article-26961-6.html
即使不与我们结盟