1.MessageQueue
消息队列,存放Message的地方,按照FIFO的规则执行。每一个线程只可以拥有一个
MessageQueue。在创建Looper对象时会创建一个MessageQueue对象。MessageQueue对象不需要我们自己创建,而是有Looper对象对其进行管理,一个线程最多只可以拥有一个MessageQueue。我们可以通过Looper.myQueue()获取当前线程中的MessageQueue。
2.Message
消息对象,存放在MessageQueue中。一个MessageQueue中可以包含多个Message对象。通过Message.obtain()或者Handler.obtainMessage()获取Message对象。但是这并不一定是直接创建一个新的实例,而是先从消息池中看有没有可用的Message实例,有就直接取出返回这个实例。没有才用给定的参数创建一个Message对象。调用removeMessage()将Message从MessageQueue中删除,同时放入到消息池中。Android系统默认情况下在消息池中实例化10个Message对象。
在Message中有几个重要的参数:arg1,arg2,what,obj
arg1和arg2:我们可以使用两个字段用来存放我们需要传递的整型值,在Service中,我们可以用来存放Service的ID。
obj:该字段是Object类型,我们可以让该字段传递某个多项到消息的接受者中。
what:这个字段可以说是消息的标志,在消息处理中,我们可以根据这个字段的不同的值进行不同的处理,类似于我们在处理Button事件时,通过switch(v.getId())判断是点击了哪个按钮。
3.Looper
操作管理MessageQueue。一个Looper对应一个MessageQueue。通过用Looper.myLooper()获得当前线程的Looper对象。Looper从MessageQueue中取出Message后交由Handler的handleMessage()方法进行处理。处理完后,调用Message.recycle()释放消息。在Android系统中,除了主线程有默认的Looper对象,其它线程默认是没有Looper对象。通过Looper.getMainLooper()获取当前应用系统中主线程的Looper对象。在这个地方有一点需要注意,假如Looper对象位于应用程序主线程中,则Looper.myLooper()和Looper.getMainLooper()获取的是同一个对象。
4.Handle
消息的处理者。负责将需要传递的信息封装成Message对象。然后调用sendMessage()方法将消息放入MessageQueue中。当MessageQueue循环到该
Message时,调用相应的handle对象的handleMessage()方法进行处理。
四者之间的关系图:
个人理解,looper像是一条高速公路,Message是高速公路上的每一辆车,当车多起来就形成车队MessageQueue,开车的人时handle。要将一个货物(代表消息)从A地(代表线程)送到B地(代表线程),A与B之间需要一条高速公路looper,货物装在每辆车上Message,送货员hanlde驾驶车Message通过高速公路looper送货。高速公路上有收费站,所有looper还要负责管理MessageQueue(车队)。
实例分析:
1.同进程之间不同组件的通信
public class MainActivity extends Activity implements OnClickListener{
private Button bt1;
private TextView tv1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv1=(TextView)findViewById(R.id.tv1);
bt1=(Button)findViewById(R.id.bt1);
bt1.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bt1:
//得到当前的looper
Looper looper=Looper.myLooper();
//创建一个handle对象,关联到looper
MyHandler mHandler=new MyHandler(looper);
//处理完后将Message从MessageQueue中移除
mHandler.removeMessages(0);
//设置传递的消息
String msgStr="主线程不同组件通信:消息来自Button";
//创建一个Message对象
Message m=mHandler.obtainMessage(1,1,1,msgStr);
//调用创建的handle对象来发送消息
mHandler.sendMessage(m);
break;
default:
break;
}
}
//创建的hanld对象的类继承Handler类
private class MyHandler extends Handler{
public MyHandler(Looper looper){
super(looper);
}
//自定义处理消息的方法
public void handleMessage(Message msg){
tv1.setText(msg.obj.toString());
}
}
}
开始的效果图:如下
点击button按钮后的效果图: