使用HandlerThread时遇到的问题

相比于AsyncTask,HandlerThread更好操控一些,因为当需要中断异步操作的时候例如:退出activity,屏幕旋转等等,虽然AsyncTask提供了中断的方法cancle( );有时候会失效,

使用HandlerThread时遇到的问题_第1张图片


从源码可以看出,它调用的是interrupt( )方法,有必要说一下java中的中断机制,Java中断机制是一种协作机制,也就是说通过中断并不能直接终止另一个线程,而需要被中断的线程自己处理中断。当调用interrupt()方法的时候,只是设置了要中断线程的中断状态。既然不能直接中断线程,那只好通过暴力方式中断了。

HandlerThread的使用

HandlerThread handlerThread = new HandlerThread("your tag");
handlerThread.start();
Looper looper = handlerThread.getLooper();
Handler handler=new Handler(looper);
{
    @Override
    public void handleMessage(Message msg) {
    if (msg.what == 0) {
    //可执行耗时操作
    }
    }
}
handler.sendEmptyMessage(0);

以上是使用HandlerThread的步骤,先创建HandlerThread对象,执行,再获取looper对象,创建Handler对象,传入looper,在handler里面重写handleMessage方法,里面可执行耗时操作,最后记得让handler发送message,根据message里面的字段来执行handleMessage方法相应的代码块。

下面是我实际开发中遇到的问题,大概功能是开一个子线程,读取所有联系人的电话号码,然后把结果到一个list中。

handlerThread = new HandlerThread("getContents");
mHandler = new Handler() {
        @Override
	public void handleMessage(Message msg) {
	    // TODO Auto-generated method stub
	    changeData(phoneNumList);	   
	    }
	};
    handlerThread.start();
	Looper looper = handlerThread.getLooper();
	final Handler mHandler1 = new Handler(looper) {
		@Override
		public void handleMessage(Message msg) {
			if (msg.what == UPDATE) {
				GetContentsUtil.init(mContext);
				phoneNumList = GetContentsUtil.getPhoneNumList();
				mHandler.sendEmptyMessage(0);
			}
		}
	};
	mHandler1.sendEmptyMessage(UPDATE);

其中这里的handlerThread和mHandler对象是activity私有的

这里为什么会有两个Handler呢?首先第一个mHandler1对应的域是子线程,执行耗时操作,获取数据之后你要更新啊,但是安卓里面只能在UI线程里面更新数据啊,很简单,再创建一个mHandler(mHandler是activity私有的,对应的域自然是UI线程),发送一个信号给它,然后更新UI的代码放在这个就可以了。


之前说到HandlerThread暴力中断,现在回归正题,

@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		// 销毁acitivity时销毁子线程
		try {
			handlerThread.getLooper().quit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		handlerThread = null;
	}

在activity销毁的时候调用,

使用HandlerThread时遇到的问题_第2张图片

直接把looper给干掉。中断当前处理的操作,后续任何发送到消息队列的消息都无效。


你可能感兴趣的:(使用HandlerThread时遇到的问题)