Android Hanlder机制分析(二) HandThread Handler.Obtain()

来源:互联网 发布:淘宝儿童玩具警车视频 编辑:程序博客网 时间:2024/05/21 08:52

(一)创建looper线程的方法比较

在上一篇中,讲到了在UI线程中Handler的原理及使用。如果我们需要在自己的子线程中创建Handler就需要自己为子线程绑定looper了。如下:

   private MyHandlerTread mHandlerThread;   mHandlerThread = new MyHandlerTread();   mHandlerThread.start();   class MyHandlerTread extends Thread {       public Handler myHandler;       public void run() {           Looper.prepare();           myHandler = new Handler() {               public void handleMessage(Message msg){               }           };           Looper.loop();       }   }

当然,我们也可以使用简单的方法对上面的方法进行实现,那就是使用HandlerThread。

       private HandlerThread myHandlerThread;       myHandlerThread= new HandlerThread("myhandler-thread");       Handler myHandler;        myHandlerThread= new HandlerThread("myhandler-thread");        myHandlerThread.start();        myHandler = new Handler(myHandlerThread.getLooper()) {            public void handleMessage(Message msg){                ......            }        };

通过HandlerThread,我们可以更加简单的将子线程变为looper线程。下面来看看HandlerThread是是怎么实现的。

public class HandlerThread extends Thread {             ......                 @Override    public void run() {        mTid = Process.myTid();        Looper.prepare();        synchronized (this) {            mLooper = Looper.myLooper();            notifyAll();        }        Process.setThreadPriority(mPriority);        onLooperPrepared();        Looper.loop();        mTid = -1;    }}    public Looper getLooper() {        if (!isAlive()) {            return null;        }

从上面的源码可以看到,在第6行和13行 同样是执行了looper.prepare()和Loop.looper();在调用new Handler(myHandlerThread.getLooper()) 的时候,实则是调用到了

public Handler(Looper looper) {        this(looper, null, false);    }    public Handler(Looper looper, Callback callback, boolean async) {        mLooper = looper;        mQueue = looper.mQueue;        mCallback = callback;        mAsynchronous = async;    }

此处就和之前的方法一样了。

(二)Handler 发送消息的两种方法比较

使用Handler的时候必然会往MessageQueue发送消息。通常的写法如下
(1)

Message msg = new Message();msg.what = xxx;msg.ar1 = XXX;mHandler.sendMessage(msg);

(1)

myHandler.sendMessage(myHandler.obtainMessage(what,arg1,arg2));

这两种方式发送消息由和区别呢?
方法一种可以看到,我们先new 了一个message,然后通过mHandler发送出去。在第二种方法中 myHandler.obtainMessage(what,arg1,arg2)的返回值也是一个message。咋然一看没有什么区别,那我们继续往下看。

public final Message obtainMessage(int what, int arg1, int arg2)    {        return Message.obtain(this, what, arg1, arg2);    }Message的obtain有多个重载方法,但是最关键的是 /**     * Return a new Message instance from the global pool. Allows us to     * avoid allocating new objects in many cases.     */    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();    }

这个方法中,会去从消息池中取出一个消息 进行清空后 返回。如果消息池为空才会去新建一个新的消息对象。因此,在每次通过handler 发送消息的时候,最好使用第二种方法,这样可以减少不必要的内存开销。

0 0