HandlerThread的使用

来源:互联网 发布:上海精神科医院 知乎 编辑:程序博客网 时间:2024/06/14 01:34

开启线程,刚开始学习时,总会使用new Thread(){ }+start()来创建,即匿名线程,创建多个线程会使程序运行越来越慢。一般会使用Handler方式来创建。这样创建的handler是在主线程即UI线程下的handler,即这个Handler是与UI线程下的Looper绑定。Looper是用于实现消息队列和消息循环机制的。那么在这个handler中执行耗时的操作是不行的,因为会影响到主线程。

因此使用HandlerThread来创建线程,实际上此类也是继承Thread类,只是比普通Thread类多一个Looper,创建HandlerThread时调用start()方法启动,然后创建Handler时将HandlerThread中的Looper对象传入。

public class ThreadDemo extends Activity{

/**
* @param args
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);

//创建HandlerThread对象
HandlerThread ht = new HandlerThread("handlerthread");

//启动此线程
ht.start();
System.out.println("------->"+Thread.currentThread().getId());

//创建Handler对象时将HandlerThread的Looper对象传入,这样Handler就会和HandlerThread这个线程绑定,否则默认是和主线程绑定的
Handler h = new Handler(ht.getLooper()){
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);

//从消息队列中读取消息,并进行拆包提取数据
Bundle b = msg.getData();
int age = b.getInt("age");
String name = b.getString("name");
System.out.println(name+" is "+age+" years old."+"------->"+Thread.currentThread().getId());
}
};

/************将消息封装成Message,并且发送到Handler--h的消息队列中去***********/
Bundle b = new Bundle();
b.putInt("age", 12);
b.putString("name", "Tom");
Message msg =h.obtainMessage();
msg.setData(b);

//将Message推送到待处理消息队列的末尾

msg.sendToTarget();

}

通过打印输出信息可以看出:

06-16 15:36:36.137: I/System.out(575): ------->1
06-16 15:36:36.137: I/System.out(575): Tom is 12 years old.------->1658

Handler---h不是运行在同一个线程中的,而通常见到的handler.post()是运行在主线程中的;

对于在封装Message时使用Message msg =h.obtainMessage(),这句等同于Message msg = new Message(),在obtainMessage方法的官方注释中写道:Return a new Message instance from the global pool. Allows us to avoid allocating new objects in many cases.(从全局池返回一个新的消息实例。使我们避免在许多情况下,分配新对象。)。obtainMessage是直接从消息池中拿出一个Message对象,不需要新开辟,new需要重新申请,效率低。

参考自哪篇博文忘记了,讲的浅显意赅,转过来自己写个Demo体会一下。

0 0
原创粉丝点击