对Android Handler Message Looper常见用法,知识点的一些总结

 

Android 非UI线程中是不能更新UI的,Handler是Android 提供的一套更新UI的机制,也是用来发送消息和处理消息的一套机制。

以前刚接触的Handler的时候,感觉总是很困惑,对Handler原理也是一知半解,现在对Handler常见用法,知识点总结一下。

先看一下谷歌Android官方文档对Handler的描述:

Class Overview


A Handler allows you to send and process Message and Runnable objects associated with a thread'sMessageQueue. Each Handler instance is associated with a single thread and that thread's message queue. When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it -- from that point on, it will deliver messages and runnables to that message queue and execute them as they come out of the message queue. 

它允许用户发送、处理消息和与线程的消息队列相关联的 runnable 对象。每一个 handler 实例都与一个单独的线程相关联。每次创建一个新的 hander 对象时,它都与创建该对象的线程或者该线程中的消息队列绑定在一起,这样handler 就可以发送消息和 runable 对象到消息队列中,并在从消息队列中取出的时候处理它们。


1. Handler的构造函数


  • Handler()   Default constructor associates this handler with the Looper for the current thread.
  • Handler(Handler.Callback callback) Constructor associates this handler with theLooper for the current thread and takes a callback interface in which you can handle messages.



 
说明:
   Handler ()是最常用的一种

   Handler(Handler.Callback callback)可以截获消息,

   Handler(Looper looper)指定了Looper对象,在实际开发中常用HandlerThread.getLooper()。


2. 关于Message


Handler如果使用sendMessage的方式把消息入队到消息队列中,需要传递一个Message对象,而在Handler中,需要重 写handleMessage()方法,用于获取工作线程传递过来的消息。

发送消息常见的方式如下,用法大同小异。

Message的参数:

  • int what:定义的消息码,一般用于设定消息的标志。
  • int arg1:简单参数
  • int arg2:简单参数
  • Object obj:传递一个任意的对象。

移除Message

  • removeMessages(int what)  
    Remove any pending posts of messages 
    with code 'what' that are in the message queue.


3. 关于Post


Post 会传递一个Runnable对象到消息队列中

Post常见方法

  • post( Runnable r)  Causes the Runnable r to be added to the message queue.
  • postDelayed( Runnable r, long delayMillis)  Causes the Runnable r to be added to the message queue, to be run after the specified amount of time elapses.
  • postAtTime( Runnable r, Object token, long uptimeMillis)  Causes the Runnable r to be added to the message queue, to be run at a specific time given byuptimeMillis.


消息队列中移除一个Runnable对象
removeCallbacks( Runnable r) Remove any pending posts of Runnable r that are in the message queue.

4. 关于MessageQueue


MessageQueue 是消息队列,在MainThread创建的时候会创建一个Looper,在创建Looper的时候,会创建MessageQueue();

5. 关于Looper


      Looper.loop()是一个死循环,用来循环查询消息队列,并把消息回传给handler。

    

6. Demo说明





1.1 发送空消息和移除消息,这里以sendEmptyMessageDelayed()为例

public class Test1 extends Activity implements OnClickListener {

	private TextView tv;
	private Button btn;
	private int i = 0;

	Handler handler = new Handler() {
		public void handleMessage(Message msg) {
			tv.setText("Hello 改变了"+i++);
			handler.sendEmptyMessageDelayed(0, 1 * 1000); //延迟一秒发送

		};
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.test1);
		setView();
		test1();

	}

	private void setView() {
		tv = (TextView) this.findViewById(R.id.tv);
		btn = (Button) this.findViewById(R.id.btn);
		btn.setOnClickListener(this);
	}

	private void test1() {

		new Thread() {
			public void run() {

				handler.sendEmptyMessageDelayed(0, 1 * 1000); //延迟一秒发送
			};
		}.start();
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {

		case R.id.btn:
			handler.removeMessages(0);//移除消息
			break;

		default:
			break;
		}

	}

}


效果图,数字每隔一秒,自增1,点击,数字会停止自增:



1.2 使用new Message(),并给Message赋值,使用handler.sendMessage(msg)发送

public class Test2 extends Activity implements OnClickListener {

	private TextView tv;


	Handler handler = new Handler() {
		public void handleMessage(Message msg) {
			
			tv.setText("msg.what=" + msg.what + ",     msg.arg1=" + msg.arg1
					+ ",    msg.arg2=" + msg.arg2 + ",    msg.obj=" + msg.obj);

		};
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.test2);
		setView();
		test();

	}

	private void setView() {
		tv = (TextView) this.findViewById(R.id.tv);

	}

	private void test() {

		new Thread() {
			public void run() {

				Message msg = new Message();
				UserBean userBean = new UserBean();
				userBean.setName("Jim");
				userBean.setPwd("123456");
				msg.what = 1;
				msg.arg1 = 2;
				msg.arg2 = 3;
				msg.obj = userBean;
				handler.sendMessage(msg);
			};
		}.start();
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
//
//		case R.id.btn:
//			handler.removeMessages(0);//移除消息
//			break;

		default:
			break;
		}

	}

}

实体类

public class UserBean {

	public String name;
	
	public String pwd;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPwd() {
		return pwd;
	}

	public void setPwd(String pwd) {
		this.pwd = pwd;
	}

	@Override
	public String toString() {
		return "UserBean [name=" + name + ", pwd=" + pwd + "]";
	}
	
	
}


效果图如下,可以看到消息成功传递和接收。



1.3 使用obtainMessage()获取已绑定的消息,并给Message赋值,使用msg.sendToTarget()发送

public class Test3 extends Activity implements OnClickListener {

	private TextView tv;

	Handler handler = new Handler() {
		public void handleMessage(Message msg) {

			tv.setText("msg.what=" + msg.what + ",     msg.arg1=" + msg.arg1
					+ ",    msg.arg2=" + msg.arg2 + ",    msg.obj=" + msg.obj);

		};
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.test3);
		setView();
		test();

	}

	private void setView() {
		tv = (TextView) this.findViewById(R.id.tv);

	}

	private void test() {

		new Thread() {
			public void run() {

				// Message msg = new Message();
				Message msg = handler.obtainMessage();
				UserBean userBean = new UserBean();
				userBean.setName("Jim");
				userBean.setPwd("123456");
				msg.what = 1;
				msg.arg1 = 2;
				msg.arg2 = 3;
				msg.obj = userBean;
				// handler.sendMessage(msg);n
				msg.sendToTarget();
			};
		}.start();
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		//
		// case R.id.btn:
		// handler.removeMessages(0);//移除消息
		// break;

		default:
			break;
		}

	}

}


效果和上图一样

Post 会传递一个Runnable对象到消息队列中

2.1 使用Post方式传递一个Runnable对象到消息队列和移除

public class Test4 extends Activity implements OnClickListener {

	private TextView tv;
	private Button btn;
	private int i = 0;

	Handler handlerPost = new Handler();
	// 线程中运行该接口的run函数
	Runnable update_thread = new Runnable() {
		public void run() {
			// System.out.println("activity_id---->"+Thread.currentThread().getId());
			// System.out.println("activity_name---->"+Thread.currentThread().getName());
			tv.setText("handlerPost:"+i++);
			// 延时1s后又将线程加入到线程队列中
			handlerPost.postDelayed(update_thread, 1000);

		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.test4);
		setView();
		System.out
				.println("activity_id0---->" + Thread.currentThread().getId());
		System.out.println("activity_name0---->"
				+ Thread.currentThread().getName());
		test();

	}

	private void setView() {
		tv = (TextView) this.findViewById(R.id.tv);
		btn = (Button) this.findViewById(R.id.btn);
		btn.setOnClickListener(this);
	}

	private void test() {

		// 将线程接口立刻送到线程队列中
		handlerPost.post(update_thread); // handler使用了post方法启动了runnbale,其实启动的线程和activity主线程是同一个线程
		// Thread t = new Thread(update_thread);
		// //这样绑定的线程与它所在的activity线程就不是同一个线程了
		// t.start();
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {

		case R.id.btn:
			handlerPost.removeCallbacks(update_thread);// 将接口从线程队列中移除
			break;

		default:
			break;
		}

	}

}

说明:
handler使用了post方法启动了runnbale,其实启动的线程和activity主线程是同一个线程

如果使用

Thread t = new Thread(update_thread);

t.start();

这样绑定的线程与它所在的activity线程就不是同一个线程了

效果图:



  Handler(Looper looper)的使用,使用handThread.getLooper()作为参数。

 注意:如果 thread.getLooper()中的thread为子线程,则会报空指针异常,因为当主线程执行Handler(Looper looper)

的时候,子线程的Looper对象还未创立。


public class Test5 extends Activity implements OnClickListener {

	private TextView tv;
	HandlerThread handThread;
	Handler handler;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.test5);
		setView();
		test();

	}

	private void setView() {
		tv = (TextView) this.findViewById(R.id.tv);

	}

	private void test() {
		
		// HandlerThread
		handThread = new HandlerThread("handThread");
		handThread.start();
		handler = new Handler(handThread.getLooper()) {
			public void handleMessage(Message msg) {

				tv.setText("HandlerThread");

			};
		};
		handler.sendEmptyMessage(0);
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		//
		// case R.id.btn:
		// handler.removeMessages(0);//移除消息
		// break;

		default:
			break;
		}

	}

}


效果图:



Demo下载地址:http://download.csdn.net/detail/yalinfendou/8477587

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值