@ZeroGeek
2018-07-03T06:30:21.000000Z
字数 6447
阅读 914
基础知识 Android知识点
消息循环处理器,内部会创建一个MessageQueue,来存放所有消息,主线程是自动创建的,新建的线程需要自己新建一个Looper对象(HandlerThread)。
public final class Looper {// sThreadLocal.get() will return null unless you've called prepare().static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();private static Looper sMainLooper; // guarded by Looper.classfinal MessageQueue mQueue; // 消息队列,存放消息final Thread mThread; // 所在线程// Handler创建前,持有的Looper必须preparepublic 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));}public static void prepareMainLooper() {prepare(false);synchronized (Looper.class) {if (sMainLooper != null) {throw new IllegalStateException("The main Looper has already been prepared.");}// 返回new的唯一一个ThreadLocal<Looper>,线程独有内存sMainLooper = myLooper();}}public static Looper getMainLooper() {synchronized (Looper.class) {return sMainLooper;}}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;Binder.clearCallingIdentity();final long ident = Binder.clearCallingIdentity();// 无限循环for (;;) {Message msg = queue.next(); // might blockif (msg == null) {return;}// ...省略输出Logmsg.target.dispatchMessage(msg);// ...msg.recycleUnchecked();}}public static Looper myLooper() {return sThreadLocal.get();}public static MessageQueue myQueue() {return myLooper().mQueue;}private Looper(boolean quitAllowed) {mQueue = new MessageQueue(quitAllowed);mThread = Thread.currentThread();}public boolean isCurrentThread() {return Thread.currentThread() == mThread;}public void quit() {mQueue.quit(false);}public void quitSafely() {mQueue.quit(true);}// ...}
prepare() : 多次调用,会产生异常。
loop():无限循环
public class Handler {public interface Callback {public boolean handleMessage(Message msg);}// 必须实现才能处理消息public void handleMessage(Message msg) {}// 由Looper的MessageQueue中的Message持有的Handler对象调用public void dispatchMessage(Message msg) {if (msg.callback != null) {handleCallback(msg);} else {if (mCallback != null) {if (mCallback.handleMessage(msg)) {return;}}handleMessage(msg);}}public Handler() {this(null, false);}public Handler(Callback callback) {this(callback, false);}public Handler(Looper looper) {this(looper, null, false);}public Handler(Looper looper, Callback callback) {this(looper, callback, false);}public Handler(boolean async) {this(null, async);}public Handler(Callback callback, boolean async) {mLooper = Looper.myLooper();// 没准备Looper会抛异常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;}// 发送消息(就是把Message添加到MessageQueue中)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);}final Looper mLooper;final MessageQueue mQueue;final Callback mCallback;final boolean mAsynchronous;IMessenger mMessenger;// ...}
消息队列,存放Message,Message是一个链表
public final class MessageQueue {// True if the message queue can be quit.private final boolean mQuitAllowed;@SuppressWarnings("unused")private long mPtr; // used by native codeMessage mMessages;private final ArrayList<IdleHandler> mIdleHandlers = new ArrayList<IdleHandler>();private SparseArray<FileDescriptorRecord> mFileDescriptorRecords;private IdleHandler[] mPendingIdleHandlers;private boolean mQuitting;}
public final class Message implements Parcelable {// 唯一标识public int what;public int arg1;public int arg2;public Object obj;public Messenger replyTo;public int sendingUid = -1;/*package*/ static final int FLAG_IN_USE = 1 << 0;/** If set message is asynchronous *//*package*/ static final int FLAG_ASYNCHRONOUS = 1 << 1;/** Flags to clear in the copyFrom method *//*package*/ static final int FLAGS_TO_CLEAR_ON_COPY_FROM = FLAG_IN_USE;/*package*/ int flags;/*package*/ long when;/*package*/ Bundle data;// 消息中持有Handler/*package*/ Handler target;/*package*/ Runnable callback;// sometimes we store linked lists of these things/*package*/ Message next;private static final Object sPoolSync = new Object();private static Message sPool;private static int sPoolSize = 0;private static final int MAX_POOL_SIZE = 50;private static boolean gCheckRecycle = true;}
需要注意的是线程默认是没有Looper的,我们在子线程使用Handler必须先创建Looper否则会发生异常。
至于主线程为什么可以直接使用Handler呢?那是因为主线程在入口的main方法中就已经帮我们创建了一个Looper对象,并开启了一个Looper循环,帮我构建好了这样一个消息消息循环的环境。
在主程序的入口main方法中进行了主线程Looper的创建以及Handler的创建,以及将改Looper与主线程绑定。然后通过Looper.loop方法进行消息的循环,不断的从消息队列(在初始化Looper的构造函数中进行了MessageQueue的初始化)取出消息,然后交给Message所持有的Handler来处理,Handler通过调用dispatchMessage()方法来处理消息。从而形成了整个消息系统机制。注意:因为我们一般使用Handler都是在主线程中,不用考虑Looper的创建,因为刚才说了,启动程序时候默认给我们创建了一个Looper对象,所在在这个环境下我们可以自由使用Handler,但是如果我们要在子线程中使用Handler就必须先通过Looper.prepare()方法创建一个Looper对象,然后创建handler对象然后通过Looper.loop()方法实Loop循环,不断的处理消息。
在子线程中创建自己的Handler和Looper,独立的消息处理系统。
public class HandlerThread extends Thread {int mPriority;int mTid = -1;Looper mLooper;private @Nullable Handler mHandler;public HandlerThread(String name) {super(name);mPriority = Process.THREAD_PRIORITY_DEFAULT;}public HandlerThread(String name, int priority) {super(name);mPriority = priority;}protected void onLooperPrepared() {}@Overridepublic 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;}// 可以获取Handler,来分发消息,然后在子线程的消息循环中处理public Handler getThreadHandler() {if (mHandler == null) {mHandler = new Handler(getLooper());}return mHandler;}public boolean quitSafely() {Looper looper = getLooper();if (looper != null) {looper.quitSafely();return true;}return false;}public int getThreadId() {return mTid;}}