handler 通过sentMessage 发送到 MessageQueue中,通过Looper的处理(可以通过Looper.myQueue()得到当前线程的消息队列)
一个for 循环 ,循环从MessageQueue中拿消息进行处理
public static void loop() { final Looper me = myLooper(); //获得当前的Looper if (me == null) { throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); } final MessageQueue queue = me.mQueue; //获取当前Looper的消息队列 //...... for (;;) { Message msg = queue.next(); //取出队头的消息 if (msg == null) { // 如果消息为空,则跳过,继续执行下一个message return; } //...... try { msg.target.dispatchMessage(msg); //...... } finally { //...... } //...... msg.recycleUnchecked(); //回收可能正在使用的消息 } }
然后通过dispatchMessage 分发到相对应的target (即发送消息的那个Handler)
handler 进行handlerMessage的回掉
APP应用启动的时候在主线程会创建一个MainLooper
所以在主线程创建的handler 是可以更新UI的 因为默认的looper在主线程,
而子线程是直接创建handler会报错,必须在创建handler之前给该子线程创建一个looper (Lopper.prepare)
new Thread(new Runnable() { public void run() { Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { Toast.makeText(getApplicationContext(), "handler msg", Toast.LENGTH_LONG).show(); } }; handler.sendEmptyMessage(1); }; }).start();
上面找个会报错
new Thread(new Runnable() { public void run() { Looper.prepare(); // 此处获取到当前线程的Looper,并且prepare() Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { Toast.makeText(getApplicationContext(), "handler msg", Toast.LENGTH_LONG).show(); } }; handler.sendEmptyMessage(1); Looper.loop();//不断遍历 消息队列中的消息 }; }).start();
一个线程有且只能绑定一个Looper,只有一个messageQueue ,可以创建无数个handler
handlerMessage 所在的线程是该looper所在的线程,即创建该Looper的线程。