Android Handler 和 Looper 的研究
2013-06-07 16:30
411 查看
// 多线程 Looper, Handler, 的确验证了handleMessage()跑在了创建 Handler 的线程之内 private void testLooper() { class MyHandlerThread extends Thread { @Override public void run() { // TODO Auto-generated method stub Logger.showLog("loopThread --> enter"); Looper.prepare(); Looper.loop(); // 如果不调用, Handler 不起作用 // Handler tHandler = new Handler(){ // 线程内直接创建,会挂掉,log显示未调用 Looper.prepare(); // // @Override // public void handleMessage(Message msg) { // // TODO Auto-generated method stub // if (msg.what == 1000) { // TestLog.showLog("I have received message 1000"); // } // super.handleMessage(msg); // } // }; // tHandler.sendEmptyMessage(1000); Logger.showLog("loopThread --> finish"); } public Looper getLooper() { return Looper.myLooper(); } } MyHandlerThread loopThread = new MyHandlerThread(); loopThread.start(); Handler tHandler = new Handler(loopThread.getLooper()) { // looper // 使用辅线程的 // ,确实是把消息跑在了与之相关的线程里 @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub if (msg.what == 1000) { Logger.showLog("I have received message 1000"); // 让线程阻塞 3s try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if (msg.what == 1001) { Logger.showLog("I have received message 1001"); } super.handleMessage(msg); } }; tHandler.sendEmptyMessage(1000); tHandler.sendEmptyMessage(1001); }
结果如下:
01-02 07:50:09.520: D/langren(1248): loopThread --> enter 01-02 07:50:09.530: D/langren(1248): I have received message 1000 01-02 07:50:12.540: D/langren(1248): I have received message 1001可以看到3s中后才收到第二条消息
在主线程(UI线程)里,如果创建Handler时不传入Looper对象,那么将直接使用主线程(UI线程)的Looper对象(系统已经帮我们创建了);在其它线程里,如果创建Handler时不传入Looper对象,那么,这个Handler将不能接收处理消息。在这种情况下,通用的作法是: class LooperThread extends Thread { public Handler mHandler; public void run() { Looper.prepare(); mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here } }; Looper.loop(); } }
这个 loop 方法是死循环,当MessageQueue 为空时阻塞。
突然意识到,可能 Activity 最后就是阻塞在这个地方,因为其中
在Handler.java的sendMessageAtTime(Message msg, long uptimeMillis)方法中,我们看到,它找到它所引用的MessageQueue,然后将Message的target设定成自己(目的是为了在处理消息环节,Message能找到正确的Handler),再将这个Message纳入到消息队列中。 抽取 Looper me = myLooper(); MessageQueue queue = me.mQueue; while (true) { Message msg = queue.next(); // might block if (msg != null) { if (msg.target == null) { // No target is a magic identifier for the quit message. return; } msg.target.dispatchMessage(msg); msg.recycle(); } } 在Looper.java的loop()函数里,我们看到,这里有一个死循环,不断地从MessageQueue中获取下一个(next方法)Message,然后通过Message中携带的target信息,交由正确的Handler处理(dispatchMessage方法)。
一直死循环等待产生事件
然后尝试在 主线程 UI 线程中创建 默认 Handler
private Handler mHandler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case 1003: Logger.showLog("I have received message 1003"); // 让线程阻塞 12s try { Thread.sleep(12000); // 出现 ANR 了,呵呵 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } break; default: break; } }; };
果然出现 ANR 了
ActivityThread 代码中果然如此
public static final void main(String[] args) { SamplingProfilerIntegration.start(); …… Looper.prepareMainLooper(); if (sMainThreadHandler == null) { sMainThreadHandler = new Handler(); } ActivityThread thread = new ActivityThread(); thread.attach(false); …… Looper.loop(); …… thread.detach(); …… Slog.i(TAG, "Main thread of " + name + " is now exiting"); } 下面仔细分析一下这个main方法。 2.Looper.prepareMainLooper(); ActivityThread其实就是我们经常说的UI thread,也就是主线程。我们都知道主线程可以使用Handler进行异步通信,因为主线程中已经创建了Looper,而这个Looper就是在这里创建的。如果其他线程需要使用Handler通信,就要自己去创建Looper。 3. sMainThreadHandler = new Handler(); 创建一个Handler。
loop 死循环就是最常见的消息循环机制了。将消息派发到正确的地方执行
相关文章推荐
- Android多线程:Looper和HandlerThread
- Android 异步消息处理机制 让你深入理解 Looper、Handler、Message三者关系
- android的消息处理机制(图文+源码分析)—Looper/Handler/Message[转]
- Android Handler,Looper,MessageQueue 机制
- [Android 知识点剖析] Looper Handler MessageQueue
- 【Android】消息系统模型及其Handler、Looper
- Android中的MessageQueue,Handler,Looper和Thread
- Android开发之多线程 ——Handler message messageQueue Looper
- android 消息系统Handler、MessageQueue、Looper源码学习
- Android中的Handler、Looper、Message简要分析
- (转载)Android 异步消息处理机制 让你深入理解 Looper、Handler、Message三者关系
- [置顶] 又一年对Android消息机制(Handler&Looper)的思考
- Android的线程使用来更新UI----Thread、Handler、Looper、TimerTask等
- android的消息处理机制 Looper,Handler,Message
- Android应用程序消息处理机制(Looper、Handler)分析(2)
- Android:消息处理机制(Handler,Message,Looper)分析
- Android 异步消息机制(Looper、Handler、MessageQueue、Message关系)
- android的消息处理机制(图+源码分析)——Looper,Handler,Message
- Android中消息系统模型和Handler Looper
- android消息机制 - Handler、Looper原理解析