handler looper和messageQueue

来源:互联网 发布:淘宝crm软件有哪些 编辑:程序博客网 时间:2024/05/17 03:32

一、使用方法。

Looper用来处理消息循环,在创建过程中会初始化MessageQueue。

Handler在其它线程发消息给当前线程

MessageQueue用来存放消息

Looper对象在哪个线程创建,Handler的handleMessage方法就在哪个线程执行

在创建activity时,android系统本身会为activity创建Looper。

final Handler mainHandler = new Handler(getMainLooper()){@Overridepublic void handleMessage(Message msg){String content = "当前线程:" + "msg:" + msg.what;Toast.makeText(MainActivity.this, content, Toast.LENGTH_SHORT).show();}};mainHandler.sendEmptyMessage(0x1);
在其它线程中使用handler消息传递时,必须自己创建looper。下面的例子中HandlerThread封装了LooperMessageQueue,还实现了获取Looper的同步机制,比较好用。
HandlerThread mThread = new HandlerThread("MyThread");mThread.start();Handler mHandle = new Handler(mThread.getLooper()){@Overridepublic void handleMessage(Message msg){String content = "当前线程:" + Thread.currentThread().getName() + "msg:" + msg.what;System.out.println(content);}};mHandle.sendEmptyMessage(0x2);

二、Looper解析

构造函数:

private Looper(boolean quitAllowed) {    mQueue = new MessageQueue(quitAllowed);    mRun = true;    mThread = Thread.currentThread();}public static void prepare() {    prepare(true);}private static void prepare(boolean quitAllowed) {    if (sThreadLocal.get() != null) {        throw new RuntimeException("Only one Looper may be created per thread");    }    sThreadLocal.set(new Looper(quitAllowed));}
在prepare中创建了Looper实例,并在Looper的构造函数中创建了MessageQueue

public static void loop() {    final Looper me = myLooper();    if (me == null) {        throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");    }    final MessageQueue queue = me.mQueue;    // Make sure the identity of this thread is that of the local process,    // and keep track of what that identity token actually is.    Binder.clearCallingIdentity();    final long ident = Binder.clearCallingIdentity();    for (;;) {        Message msg = queue.next(); // might block        if (msg == null) {            // No message indicates that the message queue is quitting.            return;        }        // This must be in a local variable, in case a UI event sets the logger        msg.target.dispatchMessage(msg);        // Make sure that during the course of dispatching the        // identity of the thread wasn't corrupted.        final long newIdent = Binder.clearCallingIdentity();        msg.recycle();    }}

在loop()中,Looper不断的通过queue.next()从MessageQueue取消息,然后调用语句msg.target.dispatchMessage(msg) 来执行。这里target为msg消息的发送者Handler,在分析Handler时再来分析,dispatchMessage在一般情况下会调用Handler类的handleMessage来处理消息,也就是上面例子中我们重载的这个handleMessage。

 

三、Handler解析

Handler的构造函数有很多,这里选带Looper参数的构造函数

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;}

再看sendMessage。

public final boolean sendEmptyMessage(int what){    return sendEmptyMessageDelayed(what, 0);}public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {    Message msg = Message.obtain();    msg.what = what;    return sendMessageDelayed(msg, delayMillis);}public final boolean sendMessageDelayed(Message msg, long delayMillis){    if (delayMillis < 0) {        delayMillis = 0;    }    return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);}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);}private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {    msg.target = this;    if (mAsynchronous) {        msg.setAsynchronous(true);    }    return queue.enqueueMessage(msg, uptimeMillis);}

sendEmptyMessage将message加到了Looper的MessageQueue中,之后Looper在loop()中调用queue.next()

在enqueueMessage里面,我们看到了msg.target = this

public void dispatchMessage(Message msg) {    if (msg.callback != null) {        handleCallback(msg);    } else {        if (mCallback != null) {            if (mCallback.handleMessage(msg)) {                return;            }        }        handleMessage(msg);    }}

如果没有设置Callback的话,就会运行handleMessage了。

 

四、HandlerThread解析

HandlerThread继承于Thread,对Looper的操作进行了封装,做了同步处理。

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;    }    // If the thread has been started, wait until the looper has been created.    synchronized (this) {        while (isAlive() && mLooper == null) {            try {                wait();            } catch (InterruptedException e) {            }        }    }    return mLooper;}


2 0
原创粉丝点击