Handler
在Handler 异步实现时,涉及到 Handler, Looper, Message,Thread四个对象
Message:消息,其中包含了消息ID,消息处理对象以及处理的数据等,由MessageQueue统一列队,终由Handler处理。
Handler:处理者,负责Message的发送及处理。使用Handler时,需要实现handleMessage(Message msg)方法来对特定的Message进行处理,例如更新UI等。
MessageQueue:消息队列,用来存放Handler发送过来的消息,并按照FIFO规则执行。当然,存放Message并非实际意义的保存,而是将Message以链表的方式串联起来的,等待Looper的抽取。
Looper:消息泵,不断地从MessageQueue中抽取Message执行。因此,一个MessageQueue需要一个Looper。
Thread:线程,负责调度整个消息循环,即消息循环的执行场所。
实现异步的流程:
主线程启动子线程 -> 子线程运行并生成Message然后发送到MessageQueue -> Looper获取Message并传递给Handler ->Handler逐个获取Looper中的Message并进行UI更新等操作。
线程在空闲(原子操作之间的间隙)时启动Looper的loop(),里面是for(;;),直到没有message才会结束。
所以HandleMessage不能有太耗时操作,message过多也会对UI刷新有影响。
Framework在Activity,Service等系统组件的主线程(UI线程---这个名称不好,比如Service就没UI)中会默认建Looper。
一个线程对应一个Looper,一个Looper对应一个MessageQueue。
每个线程最多只有一个Looper对象,它的本质是一个ThreadLocal,而ThreadLocal是在JDK1.2中引入的,它为解决多线程程序的并发问题提供了一种新思路。
子线程创建Handler要传入new Looper,如果自己定义子线程的Looper,方法如下:
public static prepare();
public static myLooper();
public static loop();
public void quit();
使用方法如下:
1. 在每个线程的run()方法中的最开始调用Looper.prepare(),这是为线程初始化消息队列。
2. 之后调用Looper.myLooper()获取此Looper对象的引用。这不是必须的,但是如果你需要保存Looper对象的话,一定要在prepare()之后,否则调用在此对象上的方法不一定有效果,如looper.quit()就不会退出。
3. 在run()方法中添加Handler来处理消息
4. 添加Looper.loop()调用,这是让线程的消息队列开始运行,可以接收消息了。
5. 在想要退出消息循环时,调用Looper.quit()注意,这个方法是要在对象上面调用,很明显,用对象的意思就是要退出具体哪个Looper。如果run()中无其他操作,线程也将终止运行。
另外一种常用方法,简便:
mHandler = new Handler(); mRunnable = new Runnable() { @Override public void run() { mTextView.setText("haha"); } }; mButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { new Thread() { public void run() { mHandler.post(mRunnable); } }.start(); } }); }
使用Handler的post()方法就显得UI的更新处理非常简单:在一个Runnable对象中更新UI,然后在另一个线程中通过Handler的post()执行该更新动作。值得注意的是,我们就算不用新开一个新线程照样可以更新UI,因为UI的更新线程就是Handler的创建线程---主线程。
表面上Handler似乎可以发送两种消息:Runnable对象和Message对象,实际上Runnable对象会被封装成Message对象。
总结:
· Handler的处理过程运行在创建Handler的线程里
· 一个Looper对应一个MessageQueue
· 一个线程对应一个Looper
· 一个Looper可以对应多个Handler
· 不确定当前线程时,更新UI时尽量调用post方法
posted on 2014-03-19 13:43 xichao1980 阅读(276) 评论(0) 编辑 收藏 举报