首页 > 代码库 > handler looper和messageQueue
handler looper和messageQueue
一、使用方法。
Looper用来处理消息循环,在创建过程中会初始化MessageQueue。
Handler在其它线程发消息给当前线程
MessageQueue用来存放消息
Looper对象在哪个线程创建,Handler的handleMessage方法就在哪个线程执行
在创建activity时,android系统本身会为activity创建Looper。
final Handler mainHandler = new Handler(getMainLooper()) { @Override public void handleMessage(Message msg) { String content = "当前线程:" + "msg:" + msg.what; Toast.makeText(MainActivity.this, content, Toast.LENGTH_SHORT).show(); } }; mainHandler.sendEmptyMessage(0x1);在其它线程中使用handler消息传递时,必须自己创建looper。下面的例子中HandlerThread封装了Looper和MessageQueue,还实现了获取Looper的同步机制,比较好用。
HandlerThread mThread = new HandlerThread("MyThread"); mThread.start(); Handler mHandle = new Handler(mThread.getLooper()) { @Override public 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 = thispublic 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; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。