android中线程分为两种:
1)系统创建的用于处理UI界面和用户交互事件的主线程
2)自己创建的用于实现其他业务的子线程
UI中的控件是线程不安全的,只能在主线程中操作控件,不能在其他子线程中直接操作控件。
如果想在其他线程中操作主线程中的控件,只能通过发送一个消息告诉主线程去更新界面。
为了便于在线程间发送消息进行通信,android实现了Handler机制。
线程间通过Handler传递消息(Message)。Message由一个FIFO的消息队列(MessageQueue)管理。
每个线程只能有一个MessageQueue, 系统默认会为主线程创建一个,而我们自己创建的子线程却没有。
正好Looper可为我们的子线程创建一个MessageQueue。
关于Looper:
1)调用Looper.prepare()为线程创建一个消息队列,并且保证只有一个。
2)Looper.loop()是一个死循环,不断从MessageQueue取出消息分发给Handler。
关于Handler:
1)创建Handler对象时,会把handler对象与该线程的消息队列进行关联。主线程默认拥有一个系统创建的消息队列,子线程默认没有,所以子线程中创建Handler对象前必须先调用Looper.prepare()创建一个。
2)必须重写handleMessage(Message msg)方法才能处理收到的消息。
3)调用Handler对象的sendMessage(Message msg)发送消息到消息队列。
子线程中处理消息应用场景:
1 new Thread(new Runnable() { 2 3 @Override 4 public void run() { 5 6 // 1.调用Looper.prepare()创建消息队列 7 Looper.prepare(); 8 // 2.创建Handler对象重写处理消息的hanleMessage()方法 9 handler3 = new Handler() { 10 11 @Override 12 public void handleMessage(Message msg) { 13 switch (msg.what) { 14 case 3: 15 break; 16 } 17 super.handleMessage(msg); 18 } 19 }; 20 // 3.调用Looper.loop()从消息队列中取消息分发给Handler; 21 Looper.loop(); 22 23 } 24 }).start();
如果需要在主线程中处理消息,则只需要创建Handler对象时重写handleMessage(), 因为主线程已经为我们创建了消息队列,所以我们不需要再调用Looper中的方法。
总结:
一个线程只能有一个消息队列(MessageQueue),一个线程可以创建多个Handler对象,他们共用该线程的一个消息队列。
系统默认会为主线程创建一个消息队列,而子线程默认没有。
1)创建Handler对象前,在子线程中必须调用Looper.prepare()为线程创建一个消息队列,主线程不需要。
2)创建Handler对象时,必须重写HandlerMessage(Message msg)回调函数用来处理Looper.loop()分发给该Handler对象的消息。
3)创建Handler对象后,在子线程中必须调用Looper.loop()从消息队列中取出消息分发给Handler对象进行处理,主线程不需要。