Android线程间通信之Handler

Handler机制及基本使用也已经是老生常谈了~~~

1、概述

Android中拒绝子线程中更新UI。且主线程中过多执行耗时操作会造成界面卡顿导致ANR影响用户体验,因此Handler线程间通信的信使应运而生。Handler有两个主要用途:(1)调度消息和runnable对象作为将来的执行;及(2)将被执行在一个不同的线程自己的方法。

1.Handler基本原理

主线程(UI线程)
子线程(work线程)
Message 消息类
MessageQueue消息队列(数据结构中的队列,先进先出规则)
这里写图片描述

Handler对象发送消息对象到消息队列中,Looper循环取出消息队列中的消息对象,并将该消息对象设置为发送该消息对象的handler的handleMessage方法的参数,若消息队列中没有消息则处于阻塞状态。

2、Handler的基本使用

1.UI线程中发送消息并在UI线程中执行

Handler发送和处理消息的几个方法:

   void  handleMessage(Message  msg):处理消息的方法,该方法通常被重写。
   final boolean hasMessage(int  what):检查消息队列中是否包含有what属性为指定值的消息
   final boolean hasMessage(int what ,Object object):检查消息队列中是否包含有what好object属性指定值的消息
   sendEmptyMessage(int what):发送空消息
   final Boolean send EmptyMessageDelayed(int what ,long delayMillis):指定多少毫秒发送空消息
   final  boolean sendMessage(Message msg):立即发送消息
   final boolean sendMessageDelayed(Message msg,long delayMillis):多少秒之后发送消息

由于代码比较简单,直接上代码了~

/**
 * Created by magic on 2016年10月23日.主线程中发送消息主线程中接收
 */
@SuppressLint("HandlerLeak")
public class MainActivity extends Activity {

	TextView textView;
	Button button;
	Handler handler = new Handler() {
		// 接收消息并处理
		public void handleMessage(Message msg) {
			System.out.println(Thread.currentThread().getName());
			// main
			System.out.println("消息->" + msg.arg1 + "-" + msg.obj);
			// 消息->1-obj消息
		};
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		button = (Button) findViewById(R.id.btn);
		button.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View arg0) {
				// 主线程中发送消息
				Message message = handler.obtainMessage();
				message.arg1 = 1;
				message.obj = "obj消息";
				handler.sendMessage(message);
				// 输出当前线程名称
				System.out.println(Thread.currentThread().getName());
				// main
			}
		});
	}

}
2.Work线程中发送消息并在UI线程中执行
/**
 * Created by magic on 2016年10月23日.Work线程中发送消息 UI线程中接收消息
 */
@SuppressLint("HandlerLeak")
public class TwoActivity extends Activity {

	Button button;
	Handler handler = new Handler() {
		// 接收消息并处理
		public void handleMessage(Message msg) {
			System.out.println(Thread.currentThread().getName());
			// main
			System.out.println("消息->" + msg.arg1 + "-" + msg.obj);
			// 消息->1-obj消息
		};
	};

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

		button = (Button) findViewById(R.id.btn);
		button.setText("Work->UI");
		button.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View arg0) {
				Thread thread = new Thread(new Runnable() {

					@Override
					public void run() {
						// work线程中发送消息
						Message message = handler.obtainMessage();
						message.arg1 = 1;
						message.obj = " obj消息";
						System.out.println(Thread.currentThread().getName());
						// Thread-400
						handler.sendMessage(message);
						// 输出当前线程名称
					}
				});
				// 开启线程
				thread.start();
			}
		});
	}
}
3.UI线程中发送消息并在Work线程执行

基本步骤:
1.准备Looper对象
2.生成handler对象
3.Looper.loop()循环取出Message对象

/**
 * Created by magic on 2016年10月23日.UI线程中发送消息 work线程中接收消息
 */
@SuppressLint("HandlerLeak")
public class ThreeActivity extends Activity {

	Button button;
	Handler handler;

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

		textView = (TextView) findViewById(R.id.tev);
		button = (Button) findViewById(R.id.btn);
		button.setText("UI->Work");
		button.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View arg0) {
				Message message = handler.obtainMessage();
				message.arg1 = 1;
				message.obj = " obj消息";
				// 主线程中发送消息
				handler.sendMessage(message);
				System.out.println(Thread.currentThread().getName());
				// main
			}
		});

		new MyThread().start();
	}

	class MyThread extends Thread {
		@Override
		public void run() {
			// 准备Looper对象
			Looper.prepare();
			handler = new Handler() {
				public void handleMessage(Message msg) {
					System.out.println(Thread.currentThread().getName());
					// Thread-401
					System.out.println("消息->" + msg.what + "-" + msg.obj);
					// 消息->0- obj消息
				};
			};
			// 循环取出消息队列中的消息对象
			Looper.loop();
			super.run();
		}
	}

}

3、Handler post方法的使用

new Handler().post(Runnable r)
new Handler().postAtFrontOfQueue(Runnable r);
new Handler().postAtTime(Runnable r, uptimeMillis);
new Handler().postAtTime(Runnable r, token, uptimeMillis);
new Handler().postDelayed(Runnable r, delayMillis);

Handler执行post方法会将参数Runnable对象,设置成Message的callback属性Message消息对象加入队列,如下:

Handler->post->Message.callback=r->join MessageQueue

该Runnable对象的run方法会在UI线程中执行,当取出Message对象时判断出该Message的callback不为null,于是调用handleCallback(msg)方法,该方法内部执行callback.run()方法。因为未开启新的线程,所以run方法内部不能执行耗时操作。

如有问题恳请指正,谢谢!

END.

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值