Android有关消息机制的理解

在安卓中线程内部与线程之间是通过Message来通讯的,这也就是传说中说的消息机制,很久都没理解。 

 首先来看看这几个类把:

     1.Message 

      消息类,也就是被要Handler封装的消息,然后send。

     注意这个类几个比较重要的字段

      a.arg1和arg2:我们可以使用两个字段用来存放我们需要传递的整型值,在Service中,我们可以用来存放Service的ID。

      b.obj:该字段是Object类型,我们可以让该字段传递某个多项到消息的接受者中。
      c.what:这个字段可以说是消息的标志,在消息处理中,我们可以根据这个字段的不同的值进行不同的处理,类似于我们在处理          Button事件时,通过switch(v.getId())判断是点击了哪个按钮。
      在使用Message时,我们可以通过new Message()创建一个Message实例,但是Android更推荐我们通过Message.obtain()或者Handler.obtainMessage()获取Message对象。这并不一定是直接创建一个新的实例,而是先从消息池中看有没有可用的Message实例,存在则直接取出并返回这个实例。反之如果消息池中没有可用的Message实例,
则根据给定的参数new一个新Message对象。通过分析源码可得知,Android系统默认情况下在消息池中实例化10个Message对象。

       2.MessageQueue
       消息队列,用来存放Message对象的数据结构,按照“先进先出”的原则存放消息。存放并非实际意义的保存,而是将Message对象以链表的方式串联起来的。MessageQueue对象不需要我们自己创建,而是有Looper对象对其进行管理,一个线程最多只可以拥有一个MessageQueue。我们可以通过Looper.myQueue()获取当前线程中的MessageQueue。

      3.Looper
        循环器,一直不断的循环从消息队列中取出消息。在一个线程中,如果存在Looper对象,则必定存在MessageQueue对象
,并且只存在一个Looper对象和一个MessageQueue对象。在Android系统中,除了主线程有默认的Looper对象,其它线程默认是没有Looper对象。如果想让我们新创建的线程拥有Looper对象时,我们首先应调用Looper.prepare()方法,然后再调用Looper.loop()方法。典型的用法如下:

       class ChildThread extends Thread{

        public void  run(){

       Looper.prepare()      ;

         ..........;

      Looper.loop();

   }

}


   4、Handler

      消息处理者,可以处理消息、发送消息。

       (个人理解):一个handler在哪个线程实例化就属于哪个线程,比如在主线程中Handler mainHandler= new Handler,这个mainHandler就属于主线程,这个mainHandler对应的消息队列就是主线程的消息队列。然后子线程要发送消息给主线程就需要通过主线程的mainHandler发送Message。反之,主线程要给子线程发送消息就需用子线程的handler发送消息。这样默认主线程中循环的looper才能取出消息。(纯属个人理解如有错误欢迎指证)


    主线程和子线程交互:

      

package com.ch.demo;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class HandlerDemoActivity extends Activity {
	private Button button;
	private TextView textView;
	public  final int SETMAIN=1; 
	public  final int SETCHLID=2; 
	public final String TAG="<-HandlerDemoActivity->";
	public Looper looper;
	private Handler chlidHandler;
	private  Handler mainhandler=new Handler(){
		public void handleMessage(Message msg) {
			switch(msg.what)
			{
			case SETMAIN: 
				textView.setText((String)msg.obj);
				  if(chlidHandler!=null){
					  Message msg2=chlidHandler.obtainMessage();
                      msg2.what=SETCHLID;
                      msg2.obj=  Thread.currentThread().getName()+"来自主线程的回复消息";
                      chlidHandler.sendMessage(msg2);
				  }
			}
			super.handleMessage(msg);
		}
	};
	
	class Chlid implements Runnable{
		
		public void run() {
            Looper.prepare();
            chlidHandler=new  Handler(){
        		public void handleMessage(Message msg) {
        			switch(msg.what)
        			{
        			case SETCHLID: 
        				Log.i(TAG, msg.obj.toString());
        			}
        		}
        	};
			Message msg=mainhandler.obtainMessage(); 
			msg.what=SETMAIN;
			msg.obj= Thread.currentThread().getName()+"来自子线程消息";
			mainhandler.sendMessage(msg);  //主线程的handler将消息压到主消息队列中。主线程的looper是启动着的
			Looper.loop();
		}
	}

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		button=(Button) findViewById(R.id.button);
		textView=(TextView) findViewById(R.id.text);
		button.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				new Thread(new Chlid()).start();
			}
		});
	}
}
运行结果:

   










  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值