相比于AsyncTask,HandlerThread更好操控一些,因为当需要中断异步操作的时候例如:退出activity,屏幕旋转等等,虽然AsyncTask提供了中断的方法cancle( );有时候会失效,
从源码可以看出,它调用的是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销毁的时候调用,
直接把looper给干掉。中断当前处理的操作,后续任何发送到消息队列的消息都无效。