Handler消息传递机制一

来源:互联网 发布:stp端口状态 编辑:程序博客网 时间:2024/05/17 01:41


android消息传递机制由消息队列MessageQuenue,Looper,Handler三部分组成。
一.MessageQuenue
消息队列——存放消息Message的数据结构,按照FIFO(先进先出原则)。
Message对象
Message.what 可以用于标记一个消息
Message.object 可以用于传递消息的具体内容,也可以传递事件——Handler.post(runnable)中的runnable就是利用object传递的。
二.Looper
消息队列的管理者.
一个线程中如果有一个Looper必有一个MessageQuenue,而且一个线程最多有一个Looper必有一个MessageQuenue,
android中主线程默认有一个Looper和MessageQuenue,
如果想在自定义的线程中启用Looper,则使用Looper.prepare(),Looper.loop();

new Thread(){
    @Overrride
    public void run(){
            Looper.prepare();
            //其他操作
           Looper.loop();   
    }
}.start();

也可以使用HanlderThread类——自带Looper
三.Handler
将消息添加进消息队列(
一般在子线程中调用Handler.sendMessage(Message)或Handler.post(Runnable);将消息添加进消息队列以实现与主线程间的通信

四。思路图


                                 


                                            1-2


java实现线程通信的方法有两种,一种是共享变量的方式,一种是管道(Pipe)方式
从1-2可以看出,消息传递机制实际上使用的是共享变量的方式实现线程通信
五。实例代码
public class MessageDemoctivity extends Activity {
    Button mBtn=null;
    TextView mTxt=null;
    Handler handler=new Handler() {
@Override
public void handleMessage(Message message){
if(message.what==1){
mTxt.setText((String)message.obj);
              }
        }
    };
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_message_democtivity);
mBtn= (Button) findViewById(R.id.test_btn);
mTxt= (TextView) findViewById(R.id.test_txt);
mBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(){
@Override
public void run(){
try {
                            Thread.sleep(3*100);//模拟获取网络数据
} catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        Message message =  Message.obtain();//获取已有Message对象或新建Message对象
message.what=1;
                        message.obj="message give you";
handler.sendMessage(message);//将Message添加进MessageQueune,Looper将Message交由Hanlder的handlerMessage处理
}
                }.start();
            }
        });
    }
}
六.源码分析
Hanlder

1.构建 Handler

创建Handler时如果没有指明关联的Looper则会默认关联当前线程的Looper(如果当前线程没有Looper则会报异常)
                                                               且会关联Looper中的消息队列


2.Handler.sendMessage(Message msg)
sendMessage(Message msg)-->
sendMessageDelayed(Message msg, long delayMillis)-->
 sendMessageAtTime(Message msg, long uptimeMillis)-->
enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis)

Handler的enqueueMessage()方法调用消息队列的enqueneMessage()方法处理Message
——即将Message添加进MessageQuenue
3.Handler.post(Runnble runnable);

Handler的post方法是将Runnable赋予Message.callblack再
通过sendMessageDealyed最终在sendMessageAtTime()中将消息添加进消息队列中


Looper

Looper的Loop方法从MessageQuenue从取出Message,并交由Message关联的Handler----
msg.tartget的dispatchMessage处理。


而在Hanler的enqueueMessage()中msg.tartget=this,即msg.target关联的是当点当前Handler


dispathcMessage根据callback是否为null交由handlerCallback或者handleMessage处理
其中handleMessage通常是我们创建Handler时要覆盖的方法
而handlerCallback只是简单地调用callback的run()方法


总结 消息的处理最终是在Looper对象中处理的(
Handler将消息添加入消息队列,Looper从消息队列中取出消息,并有调用消息关联的Handler对象处理
),而Looper在主线程中,所以消息就由子线程转由主线程处理

0 0
原创粉丝点击