什么是Handler

开门见山 解决问题

Handler是Android特有的用来异步地处理线程之间的消息传递问题的一个机制。Handler机制的本质是Android SDK 提供的一个工具类,它封装了Looper类、Message类、MessageQueue类、ThreadLocal类和一个CallBack内部接口。

使用Handler机制最主要的一个目的是为了更新UI,为了保证能让多个线程安全地并发操作主线程中的UI控件。


实例

我第一次接触Handler是在郭神的第二行代码第十章开篇,书中代码如下:

//主线程Activity内实现匿名内部类
private Handler mHandler = new Handler(){
	public void handleMessage(Message msg){
		switch (msg.what){
			case 1:
				//UI操作
				break;
			default:
				break;
		}
	}
}


//同一Activity内子线程代码
@Override
public void onClick(View v){
	switch(v.getID()){
		case R.id.btn_change_UI:
			new Thread(new Runnable(){
				@Override
				public void run(){
					Thread.sleep(1000//耗时操作
					**Message mMessage = new Message();
					mMessage.what = UPDATE_UI;
					mHandler sendMessage(mMessage);**
				}
			}).start();
			break;
		default:
			break;
		}
	}
} 

上段代码中,在Activity中使用Handler匿名内部类并重写其handleMessage方法,该方法内通过获取传入Message的what变量,用switch实现不同的UI操作。
子线程中执行耗时操作后通过前文的mHandler对象,用sendMessage方法将处理后的Message实例对象发送出去。Message回到UI线程执行switch中相关的case的内容。
除了更新UI,Handler还能实现一些比较简单的小功能,比如实现再按一次返回键退出应用的功能。

 private static boolean isExit = false;

    Handler mHandler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            isExit = false;
        }
    };

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

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            exit();
            return false;
        }
        return super.onKeyDown(keyCode, event);
    }

    private void exit() {
        if (!isExit) {
            isExit = true;
            Toast.makeText(getApplicationContext(), "再按一次退出程序",
                    Toast.LENGTH_SHORT).show();
            // 利用handler延迟发送更改状态信息
            mHandler.sendEmptyMessageDelayed(0, 2000);
        } else {
            finish();
            System.exit(0);
        }
    }

}

当然,实现该功能有很多别的高效的办法,这里只是给出一种思路。


涉及的类

在开篇提到了Handler机制涉及Handler、Looper、Message、MessageQueue、ThreadLocal几个类。

类名作用包名
Handler添加Message到MessageQueue
处理Looper分派的Message
android.os.Handler
Looper获取MessageQueue内的Message
将Message分发给各个Handler对象
android.os.Looper
Message线程间通信的数据单元,存储通讯信息android.os.Message
MessageQueue存储Handler发来的Messageandroid.os.MessageQueue
ThreadLocal线程本地变量,用来存储当前线程信息java.lang.ThreadLocal< T >

工作原理

Handler机制主要涉及如下流程:

  1. 异步通信准备:在主线程中创建Looper、MessageQueue、Handler对象
  2. 消息发送:子线程通过Handler对象发送Message到MessageQueue
  3. 消息循环:Looper从MessageQueue取出Message并分发给对应Handler
  4. 消息处理:Handler接收Message并根据Message中的信息进行相关操作

流程图如下:
在这里插入图片描述

需要注意的是:

  • 一个Thread只能绑定一个Looper
  • 一个Looper能绑定多个Handler
  • 一个Handler只能绑定一个Looper

那么如何保证一个Thread只包含一个Looper对象呢?这就要提到ThreadLocal。
Looper 类下prepare方法用来给当前线程初始化一个looper,根据ThreadLocal内的信息,来判断是否需要new一个新的loope,源码如下:

// Looper.java
private static void prepare(boolean quitAllowed) {
    if (sThreadLocal.get() != null) {
        throw new RuntimeException("Only one Looper may be created per thread");
    }
    sThreadLocal.set(new Looper(quitAllowed));
}
  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值