Handler的小结

Handler在android里负责发送和处理消息。它的主要用途有:

  1)按计划在将来的某个时刻发送消息或执行某个Runnanble(使用POST方法);
  2)从其他线程中发送来的消息放入消息队列中,进行任务排队,避免线程冲突(常见于更新UI线程)

   默认情况下,Handler接受的是当前线程下的消息循环实例(使用Handler(Looper looper)、Handler(Looper  looper, Handler.Callback callback) 可以指定线程),同时一个消息队列可以被当前线程中的多个对象进行分发、处理(在UI线程中,系统已经有一个Activity来处理了,你可以再起若干个 Handler来处理)。在实例化Handler的时候,Looper可以是任意线程的,只要有Handler的指针,任何线程也都可以 sendMessage。Handler对于Message的处理不是并发的。一个Looper 只有处理完一条Message才会读取下一条,所以消息的处理是阻塞形式的(handleMessage()方法里不应该有耗时操作,可以将耗时操作放在其他线程执行,操作完后发送Message(通过sendMessges方法),然后由handleMessage()更新UI)。


在系统的music的源码中有一段自定义了HandleThread,

    private static class Worker implements Runnable {
        private final Object mLock = new Object();
        private Looper mLooper;
        
        /**
         * Creates a worker thread with the given name. The thread
         * then runs a {@link android.os.Looper}.
         * @param name A name for the new thread
         */
        Worker(String name) {
            Thread t = new Thread(null, this, name);
            t.setPriority(Thread.MIN_PRIORITY);
            t.start();
            synchronized (mLock) {
                while (mLooper == null) {
                    try {
                        mLock.wait();
                    } catch (InterruptedException ex) {
                    }
                }
            }
        }
        
        public Looper getLooper() {
            return mLooper;
        }
        
        public void run() {
            synchronized (mLock) {
                Looper.prepare();
                mLooper = Looper.myLooper();
                mLock.notifyAll();
            }
            Looper.loop();
        }
        
        public void quit() {
            mLooper.quit();
        }
    }
初始化的时候

        mAlbumArtWorker = new Worker("album art worker");
        mAlbumArtHandler = new AlbumArtHandler(mAlbumArtWorker.getLooper());

退出的时候

    @Override
    public void onDestroy()
    {
        mAlbumArtWorker.quit();
        super.onDestroy();
        //System.out.println("***************** playback activity onDestroy\n");
    }


       Looper 
        Looper扮演着一个Handler和 消息队列之间通讯桥梁的角色。程序组件首先通过Handler把 消息传递给Looper,Looper把 消息放入队列。Looper也 把消息队列里的消息广播给所有的Handler,Handler接 受到消息后调用handleMessage进 行处理。 

       1)   可以通过Looper类 的静态方法Looper.myLooper得 到当前线程的Looper实 例,如果当前线程未关联一个Looper实 例,该方法将返回空(null)它不会抛空指针异常。 

       2)   可以通过静态方法Looper. getMainLooper方法得到主线程的Looper实 例 这里需要注意一下 主线程默认是有一个Looper对象的。但是我们自己定义的子线程没有的。那么我们怎么在子线程中得到Looper对象呢?如果一个线程中调用Looper.prepare(),那么系统就会自动的为该线程建立一个消息队列,然后调用 Looper.loop();之后就进入了消息循环,这个之后就可以发消息、取消息、和处理消息。这个如何发送消息和如何处理消息可以再其他的线程中通过 Handle来做,但前提是我们的Hanle知道这个子线程的Looper,但是你如果不是在子线程运行 Looper.myLooper(),一般是得不到子线程的looper的。


同样的可以用HandlerThread来代替,HandlerThread继承于Thread,所以它本质就是个Thread。与普通Thread的差别就在于,它有个Looper成员变量。这个Looper其实就是对消息队列以及队列处理逻辑的封装,简单说就是 消息队列+消息循环。

HandlerThread handlerThread = new HandlerThread("threadone");   
handlerThread.start();   
mHandler =  new Handler(handlerThread.getLooper());   

参考 http://www.cnblogs.com/moonvan/archive/2011/04/22/2024979.html

阅读更多
个人分类: android
想对作者说点什么? 我来说一句

Handler机制

2017年12月15日 1.92MB 下载

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭