Handler原理
2020-04-23 本文已影响0人
Android刘东
1.Handler构造函数
public Handler() {
this(null, false);
}
public Handler(@Nullable Callback callback) {
this(callback, false);
}
public Handler(@NonNull Looper looper) {
this(looper, null, false);
}
public Handler(@NonNull Looper looper, @Nullable Callback callback) {
this(looper, callback, false);
}
public Handler(boolean async) {
this(null, async);
}
public Handler(@Nullable Callback callback, boolean async) {
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread " + Thread.currentThread()
+ " that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
注意:工作线程需要传Looper.Mylooper()否则
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread " + Thread.currentThread()
+ " that has not called Looper.prepare()");
}
2.Looper,MessageQueue对象
Looper每个线程只有一个,工作线程可以Looper.myLooper()传参
主线程的Looper是由ActivityThread.java中main函数创建代码如下:
public static void main(String[] args) {
//省去部分代码
Looper.prepareMainLooper();//创建对象
Looper.loop();//开始轮询
}
///Looper类
public static void prepareMainLooper() {
prepare(false);
synchronized (Looper.class) {
if (sMainLooper != null) {
throw new IllegalStateException("The main Looper has already been prepared.");
}
sMainLooper = myLooper();
}
}
private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
//创建Looper对象
sThreadLocal.set(new Looper(quitAllowed));
}
private Looper(boolean quitAllowed) {
//创建MessageQueued对象
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
3.Handler.SendMessage()方法
//省去部分代码
public final boolean sendMessage(@NonNull Message msg) {
return sendMessageDelayed(msg, 0);
}
public final boolean sendMessageDelayed(@NonNull Message msg, long delayMillis) {
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
public boolean sendMessageAtTime(@NonNull Message msg, long uptimeMillis) {
MessageQueue queue = mQueue;
return enqueueMessage(queue, msg, uptimeMillis);
}
4.添加到消息队列
boolean enqueueMessage(Message msg, long when) {
synchronized (this) {
needWake = mBlocked && p.target == null && msg.isAsynchronous();
Message prev;
for (;;) {
prev = p;
p = p.next;
if (p == null || when < p.when) {
break;
}
// 判断消息队列里有消息,将消息插入到队列中
if (needWake && p.isAsynchronous()) {
needWake = false;
}
}
msg.next = p; // invariant: p == prev.next
prev.next = msg;
}
// We can assume mPtr != 0 because mQuitting is false.
if (needWake) {
nativeWake(mPtr);
}
}
return true;
}
5.Loop无限循环
public static void loop() {
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
//msg.target相当于Handler.dispatchMessage(msg);
msg.target.dispatchMessage(msg);
}
5.Handler.dispatchMessage方法
public void dispatchMessage(@NonNull Message msg) {
if (msg.callback != null) {
//如Handler构造函数为:
//new Handler(
// new Handler.Callback() {
// @Override
// public boolean handleMessage(@NonNull Message msg) {
//
// }
// }
// );
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);//回调
}
}
6.Handler中sendMessage和Post区别
public final boolean post(@NonNull Runnable r) {
return sendMessageDelayed(getPostMessage(r), 0);
}
多了一层getPostMessage(r)。
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;
return m;
}
1.post方法:回调在run方法2.sendMessage回调在Handler.handleMessage()或者Handler的callback中
7.Message构造建议
Message mMessage =Message.obtain();
而不是,因为Message.obtain()复用了
Message mMessage =new Message();
8.Looper无线循环为什么不ANR
1.ActivityThread的main方法主要就是做消息循环,一旦退出消息循环,那么你的应用也就退出了.
2.造成ANR的原因一般有两种:
1)当前的事件没有机会得到处理(即主线程正在处理前一个事件,没有及时的完成或者 looper被某种原因阻塞住了)
2)当前的事件正在处理,但没有及时完成
3.Looer.loop()方法可能会引起主线程的阻塞,但只要它的消息循环没有被阻塞,能一直处理事件就不会产生ANR异常。