@ZeroGeek
2018-07-03T06:30:21.000000Z
字数 6447
阅读 795
基础知识
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.class
final MessageQueue mQueue; // 消息队列,存放消息
final Thread mThread; // 所在线程
// Handler创建前,持有的Looper必须prepare
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));
}
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 block
if (msg == null) {
return;
}
// ...省略输出Log
msg.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 code
Message 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() {
}
@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;
}
// 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;
}
}