Handler.post(Runnable r)
我們都知道Handler中的post方法,并且也是經常使用它
handler.post(newRunnable()? ? {? ? @Overridepublicvoidrun(){? ? ? ? //dosomething}});
用它可以更新一個組件的內容,我們也知道Hanlder中也有一個handler.sendMessage(Message msg)方法,這兩個方法有什么區別呢?先看一下Message類中定義一個私有的變量:Runnable callback;
再來看一下handler.post(Runnable callback)方法的
publicfinalbooleanpost(Runnable r){returnsendMessageDelayed(getPostMessage(r),0);? ? ? }
再看一下sendMessageDelayed的源碼:
publicfinalbooleansendMessageDelayed(Message msg,longdelayMillis){if(delayMillis <0) {? ? ? ? ? ? ? delayMillis =0;? ? ? ? ? ? }returnsendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);}
這里面有個關鍵就是方法getPostMessage(r)這個方法,他將Runnable轉成一個Message,他內部到底干了什么呢?看一下他的源碼:
privatefinalMessagegetPostMessage(Runnable r){? ? ? ? ? Message m = Message.obtain();? ? ? ? ? m.callback = r;returnm;? ? }
這里面就是將Runnable轉化成一個Message,其他看他的代碼很簡單,就是先獲取一個空消息Message.obtain(),然后將Message中的callback的值設置成Runnable,這時候就了解到了Message中的callback的作用了!
當Looper對象所屬的線程在Looper.Loop方法中循環執行從MessageQueue隊列讀取Message對象,并把Message對象交給Handler處理,調用Handler的dispatchmessage方法。
看一下dispatchMessage的源碼
publicvoiddispatchMessage(Message msg){if(msg.callback !=null) {? ? ? handleCallback(msg);? }else{if(mCallback !=null) {if(mCallback.handleMessage(msg)) {return;? ? ? ? ? ? }? ? ? }? ? ? handleMessage(msg);? }}
從dispatchMessage定義可以看出,如果Message對象自帶callback對象,handler不會執行handleMessage方法而是執行message.callback中定義的run方法,當然callback還是在handler關聯的looper所綁定的線程中執行的。實際上Handler.post(Runnable r)方法就是把r添加到一個msg.callback的。
View.post(Runnable r)
看一下實例代碼:
finalButton btn = (Button)findViewById(R.id.btn);btn.post(newRunnable(){@Overridepublicvoidrun(){? ? ? ? ? btn.setText("不是好人");? ? ? } }); }
上面的代碼就是更新btn中的內容,同樣下面的代碼也可以達到這種效果:
Handlerhandler=newHandler();final Button btn = (Button)findViewById(R.id.btn);handler.post(newRunnable(){? ? @Overridepublicvoidrun() {? ? ? ? ? btn.setText("不是好人");}}); }
不同是這個是用handler.post方法,一個是用View.post方法,現在來看一下View.post方法的源代碼:
public boolean post(Runnable action) {Handlerhandler;AttachInfo attachInfo = mAttachInfo;? ? ? ? if (attachInfo != null) {handler= attachInfo.mHandler;} else {? ? ? ? ? ? // Assume that post will succeed later? ? ? ? ? ? ViewRootImpl.getRunQueue().post(action);? ? ? ? ? ? return true;? ? ? ? }? ? ? ? returnhandler.post(action);}
方法中主要的功能代碼就是attachInfo.mHandler,獲取當前線程的hanlder,和我們在一個線程中定義一個Handler的效果是一樣的。
原文鏈接:http://www.lxweimin.com/p/d3a782b076c1