做爲一個Android開發者,咱們確定熟悉並使用過Handler機制。最經常使用的使用場景是「在子線程更新ui」,實際上咱們知道上面的說話是錯誤的。由於Android中只有主線程才能更新ui,那麼當咱們在子線程獲得更新ui通知的時候怎麼辦?此刻Handler存在的意義就體現出來了。咱們在子線程用handler發送一個消息通知給主線程,而後讓主線程更新ui,這樣問題就解決了。下面讓咱們看看handler怎麼使用的吧!!!ide
<一>Handler的基本使用源碼分析
public class HandlerActivity extends Activity private final String TAG = "HandlerActivity.class"; private Handler mHandler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); Log.d(TAG,"arg1------"+msg.arg1); --- 1 Log.d(TAG,"arg2------"+msg.arg2); --- 2 Person person = (Person) msg.obj; if (person != null ){ Log.d(TAG,"person.age------"+person.getAge()); --- 555 Log.d(TAG,"person.name------"+person.getName()); --- Liu } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_handler); new Thread(new Runnable() { @Override public void run() { /** * 傳遞簡單Integer類型消息 */ Message message = new Message(); message.arg1 = 1; message.arg2 = 2; /** * 傳遞複雜消息 */ Person person = new Person(); person.setAge(555); person.setName("Liu"); message.obj = person; mHandler.sendMessage(message); } }).start(); } }
由上可見,咱們在使用handler發送消息的時候,而且能夠傳遞一些數據信息。在傳遞消息的時候咱們用到了Message,並經過new的方式實例化。下面讓咱們看一下獲取Message的第二種方法。ui
<二>獲取Message的另外一種方式以及源碼分析this
Message message = mHandler.obtainMessage();
message.sendToTarget();
同第一種方式相比,獲取Message和發送Message的方法都不同了。其實若是跟進源碼你能夠發現,這種方式其實就是把第一種方式封裝了一下,跟隨我看一下源碼吧!!!spa
首先先來看一下獲取Message的方法,入口是在Handler的obtainMessage方法:線程
public final Message obtainMessage(){ return Message.obtain(this); }
繼續跟Message的obtain方法code
public static Message obtain(Handler h) { Message m = obtain(); m.target = h; return m; }
在這裏咱們看到有兩步操做,一個是調用本類的obtain方法,另外一個是將Handler引用賦值給Message的target對象。接下來看一下obtain方法對象
public static Message obtain() { synchronized (sPoolSync) { if (sPool != null) { Message m = sPool; sPool = m.next; m.next = null; m.flags = 0; // clear in-use flag sPoolSize--; return m; } } return new Message(); }
咱們看到最後實例化的方式和第一種意義,都是經過new的方法。好了!!!消息獲取到了,下面看看它是怎麼發送消息的吧!!!,直接看Message的sendToTarget方法。blog
public void sendToTarget() { target.sendMessage(this); }
還記得咱們以前給target賦值的是什麼嗎?沒錯,就是handler,因此第二種方式其實就是對第一種方式的封裝。隊列
<三>Handler的七種發信息的方法
上面咱們是經過Handler的sendMessage(Message msg)發送消息的,下面在來看看Handler的其餘六種發送消息方式。這六種方法又分爲兩類:
(一) 攜帶消息Message
1> sendMessageAtTime(Message msg, long uptimeMillis) 在指定時間發送消息到隊列
2> sendMessageAtFrontOfQueue(Message msg) 當即發送Message到隊列,並且是放在隊列的最前面
3> sendMessageDelayed(Message msg, long delayMillis) 延遲delayMillis時間發送消息到隊列
(二) 不攜帶消息Message
4> sendEmptyMessage(int what) 發送空消息到隊列
5> sendEmptyMessageAtTime(int what, long uptimeMillis) 在指定時間發送空消息到隊列
6> sendEmptyMessageDelayed(int what, long delayMillis) 延遲delayMillis發送空消息到隊列
跟蹤源碼你會發現,這幾個方法最終調用的都是 sendMessageAtTime,以下圖: