Android 中Handler

文章出处:http://blog.csdn.net/shift_wwx

请转载的朋友标明出处~~


之前 Android异步消息处理线程之----Looper+MessageQueue+Handler 一文中将了一下Android 中异步消息处理的流程。

网上对于Handler 的讲解很详细了,这里根据 Source code 说一下Handler。


/**
 * A Handler allows you to send and process {@link Message} and Runnable
 * objects associated with a thread's {@link MessageQueue}.  Each Handler
 * instance is associated with a single thread and that thread's message
 * queue.  When you create a new Handler, it is bound to the thread /
 * message queue of the thread that is creating it -- from that point on,
 * it will deliver messages and runnables to that message queue and execute
 * them as they come out of the message queue.

Handler 是用来发送和处理与一个线程的MessageQueue 有关联的Message 和 Runnable。

一个Handler 与一个线程以及此线程的MessageQueue有关联。

新建一个Handler 的时候,要与一个已经创建好的线程的MessageQueue 绑定。这样Handler 就可以发送message 和runnable 到消息队列,并且处理从消息队列发出来的回调。


构造函数就不一一附上,其中有参数的,没参数的。没参数的构造是指callback 为null。有参数的构造有传callback,looper或是looper + callback等。

主要来看一下:

    public Handler(Callback callback, boolean async) {
        if (FIND_POTENTIAL_LEAKS) {
            final Class<? extends Handler> klass = getClass();
            if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
                    (klass.getModifiers() & Modifier.STATIC) == 0) {
                Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
                    klass.getCanonicalName());
            }
        }

        mLooper = Looper.myLooper();
        if (mLooper == null) {
            throw new RuntimeException(
                "Can't create handler inside thread that has not called Looper.prepare()");
        }
        mQueue = mLooper.mQueue;
        mCallback = callback;
        mAsynchronous = async;
    }
这里可以看到 Android异步消息处理线程之----Looper+MessageQueue+Handler 中说到的,handler对象只能添加到有消息队列的线程中。


通过构造函数可以看到,handler 是创建的时候可以不传Looper,那也就是说这个时候的handler 是在主线程中,也就是UI线程。在应用中可能一些费时、阻塞的东西可以通过消息队列来处理,这个时候可以新建一个Thread,将Thread 中处理消息队列,最后通过handleMessage 在主线程中处理UI 的操作。

那么关键就是消息队列的形成:

通过 Handler sendMessage 与 obtainMessage (sendToTarget)比较 看到,我们还是尽量用obtainMessage 来获取msg obj

    public final Message obtainMessage(int what)
    {
        return Message.obtain(this, what);
    }
    public void sendToTarget() {
        target.sendMessage(this);
    }
至于new Message 与obtainMessage 有什么区别,可以看一下 Handler sendMessage 与 obtainMessage (sendToTarget)比较

最终会调用到:

    public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
        MessageQueue queue = mQueue;
        if (queue == null) {
            RuntimeException e = new RuntimeException(
                    this + " sendMessageAtTime() called with no mQueue");
            Log.w("Looper", e.getMessage(), e);
            return false;
        }
        return enqueueMessage(queue, msg, uptimeMillis);
    }
最终会往handler 所在的Lopper 里面的MessageQueue 存msg。

通过 Android异步消息处理线程之----Looper+MessageQueue+Handler 知道Looper.loop就是一直处理消息队列,没有就挂靠起来。loop 会去处理每一个msg:

msg.target.dispatchMessage(msg);

    public void dispatchMessage(Message msg) {
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg);
        }
    }
这个逻辑也是需要注意的:

1)当handler 有Runnable 处理的时候,会去处理Runnable

public final boolean post(Runnable r)
{
   return  sendMessageDelayed(getPostMessage(r), 0);
}

public final boolean postAtTime(Runnable r, long uptimeMillis)
{
    return sendMessageAtTime(getPostMessage(r), uptimeMillis);
}

public final boolean postAtTime(Runnable r, Object token, long uptimeMillis)
{
    return sendMessageAtTime(getPostMessage(r, token), uptimeMillis);
}

public final boolean postDelayed(Runnable r, long delayMillis)
{
    return sendMessageDelayed(getPostMessage(r), delayMillis);
}

public final boolean postAtFrontOfQueue(Runnable r)
{
    return sendMessageAtFrontOfQueue(getPostMessage(r));
}
2)如果没有Runnable 有Callback 的时候,处理Callback

    public interface Callback {
        public boolean handleMessage(Message msg);
    }
3)如果上面都没有,如果需要处理msg,就需要override handler的函数
    public void handleMessage(Message msg) {
    }

删除Runnable 和 msg 可以通过:

public final void removeCallbacks(Runnable r)
{
    mQueue.removeMessages(this, r, null);
}

public final void removeCallbacks(Runnable r, Object token)
{
    mQueue.removeMessages(this, r, token);
}
public final void removeMessages(int what) {
    mQueue.removeMessages(this, what, null);
}

public final void removeMessages(int what, Object object) {
    mQueue.removeMessages(this, what, object);
}


还有一个Andrid 类可以直接用,可以看一下 Android HandlerThread






你可能感兴趣的:(thread,android,handler)