Handler使用(二)
Handler为Android提供了一种异步消息处理机制,当向消息队列中发送消息(sendMessage)后就立即返回,而从消息队列中读取消息时会阻塞,其中从消息队列中读取消息时会执行Handler中的handleMessage方法,因此在创建Handler对象时,应使用匿名内部类重写该方法,在该方法中写上读取到消息后的操作,使用Handler的obtainMessage()方法来获得消息对象。
Handler与线程的关系:
?
使用Handler对象中的post方法可以将Runnable对象添加到Handler的线程队列中,该Runnanble的执行其实并未单独开启线程,而是仍然在当前Activity线程中执行的。Handler对象中是调用了Runnanble对象的run方法。
?
如何让Handler执行Runnanble时打开新的线程?????
1.???????首先生成一个HandlerThread对象,实现了使用Looper来处理消息队列的功能,这个类由Android应用程序框架提供。HandlerThread XXX=new HandlerThread(“handler_thread”);
2.???????在使用HandlerThread的getLooper()方法之前,必须先调用该类的start()方法。
3.???????根据这个HandlerThread对象得到其中的Looper对象。
4.???????创建自定义的继承于Hanlder类的子类,其中实现一个参数为Looper对象的构造函数方法,方法内容调用父类的构造函数即可。
5.???????使用第三步得到的Looper对象创建自定义的Handler子类的对象,再将消息发送到该Handler的消息队列中,Handler复写的handleMessage()将会执行来处理消息队列中的消息,即Message对象,可以使用arg1,arg2,Object传递一些整型或对象,还可用Message对象的setData()来将Bundle对象传递给新创建的线程,新创建的线程在执行handleMessage()时可从message中利用getData()提取出Bundle对象来进行处理。
?
Java示例代码:
//自定义继承于Hanlder的子类,
????class?MyHandler?extends?Handler
????{
????//实现一个参数?为Looper对象的构造函数的方法,内容只需调用父类的构造函数即可。
????public?MyHandler(Looper looper)
????{
?????????super(looper);
????}
???????/* (non-Javadoc)
????????*?复写handleMessage方法来处理消息,即Message对象;
????????*/
???????@Override
???????public?void?handleMessage(Message msg) {
???????????//?TODO?Auto-generated method stub????????
???????????Bundle bundle=msg.getData();?
???????????System.out.println("username:"+bundle.getString("name")+"?password:"+bundle.getString("password"));
???????????System.out.println("Handler---------->"+
Thread.currentThread().getId());
???????????super.handleMessage(msg);
???????}
????}
???
????public?void?beginSendMessageClick(View view) {
?
????//生成一个HandlerThread对象;
?????HandlerThread handlerThread=new?HandlerThread("handler_thread");?
?????//调用getLooper方法前必须调用此方法;
?????handlerThread.start();
?????//得到Looper对象;
?????Looper looper=handlerThread.getLooper();
?????//创建自定义的Handler子类的对象
?????MyHandler myHandler=new?MyHandler(looper);
?????
//直接从Handler对象中获取message;另外?一种写法是直接调用Handler对象中的sendMessage方法,
?????Message msg=myHandler.obtainMessage();
??????Bundle bundle=new?Bundle();
??????bundle.putString("name",?"administrator");
??????bundle.putString("password",?"admin_password");
??????msg.setData(bundle);
?????//将Message发送到目标对象,该对象是生成msg对象的Handler对象-->myHandler;
??????msg.sendToTarget();
????}
?
?
/*小结:
?* 1.向哪个Handler发送消息,就必须在哪个Handler里接收。
?* 2.直接使用Java的Thread是无法更新Android?UI的,因为Android?View在设计时,线程是不完全的,
?*???3.?直接使用Handler中的post方法是在当前主线程中做操作,而不是新建线程,建议使用Thread线程新建或用HandlerThread类亦可以;
?*/