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,如下图:

  

 

posted @ 2016-12-27 21:41  梦一场yu  阅读(1043)  评论(0编辑  收藏  举报