Handler系列之使用

  作为一个Android开发者,我们肯定熟悉并使用过Handler机制。最常用的使用场景是“在子线程更新ui”,实际上我们知道上面的说话是错误的。因为Android中只有主线程才能更新ui,那么当我们在子线程得到更新ui通知的时候怎么办?此刻Handler存在的意义就体现出来了。我们在子线程用handler发送一个消息通知给主线程,然后让主线程更新ui,这样问题就解决了。下面让我们看看handler怎么使用的吧!!!

<一>Handler的基本使用

public class HandlerActivity extends Activity 

    private final String TAG = "HandlerActivity.class";

    private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Log.d(TAG,"arg1------"+msg.arg1); --- 1
Log.d(TAG,"arg2------"+msg.arg2); --- 2
Person person = (Person) msg.obj;
if (person != null ){
Log.d(TAG,"person.age------"+person.getAge()); --- 555
Log.d(TAG,"person.name------"+person.getName()); --- Liu
}
}
}; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_handler); new Thread(new Runnable() {
@Override
public void run() {
/**
* 传递简单Integer类型消息
*/
Message message = new Message();
message.arg1 = 1;
message.arg2 = 2; /**
* 传递复杂消息
*/
Person person = new Person();
person.setAge(555);
person.setName("Liu");
message.obj = person; mHandler.sendMessage(message);
}
}).start();
}
}

    由上可见,我们在使用handler发送消息的时候,并且可以传递一些数据信息。在传递消息的时候我们用到了Message,并通过new的方式实例化。下面让我们看一下获取Message的第二种方法。

<二>获取Message的另一种方式以及源码分析

                Message message = mHandler.obtainMessage();
message.sendToTarget();

同第一种方式相比,获取Message和发送Message的方法都不一样了。其实如果跟进源码你可以发现,这种方式其实就是把第一种方式封装了一下,跟随我看一下源码吧!!!

首先先来看一下获取Message的方法,入口是在Handler的obtainMessage方法:

    public final Message obtainMessage(){
return Message.obtain(this);
}

继续跟Message的obtain方法

   public static Message obtain(Handler h) {
Message m = obtain();
m.target = h;
return m;
}

  在这里我们看到有两步操作,一个是调用本类的obtain方法,另一个是将Handler引用赋值给Message的target对象。接下来看一下obtain方法

    public static Message obtain() {
synchronized (sPoolSync) {
if (sPool != null) {
Message m = sPool;
sPool = m.next;
m.next = null;
m.flags = 0; // clear in-use flag
sPoolSize--;
return m;
}
}
return new Message();
}

  我们看到最后实例化的方式和第一种意义,都是通过new的方法。好了!!!消息获取到了,下面看看它是怎么发送消息的吧!!!,直接看Message的sendToTarget方法。

    public void sendToTarget() {
target.sendMessage(this);
}

还记得我们之前给target赋值的是什么吗?没错,就是handler,所以第二种方式其实就是对第一种方式的封装。

<三>Handler的七种发信息的方法

  上面我们是通过Handler的sendMessage(Message msg)发送消息的,下面在来看看Handler的其他六种发送消息方式。这六种方法又分为两类:

    (一) 携带消息Message

      1> sendMessageAtTime(Message msg, long uptimeMillis)     在指定时间发送消息到队列

      2> sendMessageAtFrontOfQueue(Message msg)  立即发送Message到队列,而且是放在队列的最前面

      3> sendMessageDelayed(Message msg, long delayMillis)  延迟delayMillis时间发送消息到队列

    (二) 不携带消息Message

      4> sendEmptyMessage(int what)   发送空消息到队列

      5> sendEmptyMessageAtTime(int what, long uptimeMillis)  在指定时间发送空消息到队列

      6> sendEmptyMessageDelayed(int what, long delayMillis) 延迟delayMillis发送空消息到队列

  跟踪源码你会发现,这几个方法最终调用的都是 sendMessageAtTime,如下图:

  Handler系列之使用

上一篇:简单的php基于curl的反向代理程序


下一篇:SpringMVC List绑定