Android面试题-Handler机制

Android⾯试题-Handler机制
Handler机制相信很多⼈在⾯试Android岗的时候都会被问到相关的问题,虽然已经有很多⼈整理了,但我还是想⾃⼰整理⼀下,权当是给⾃⼰的加深⾃⼰对于handler机制的理解。
⾸先我们先了解下关于Handler的四个主要组成部分:Handler、Looper、Messagequeue、Message
Looper :负责关联线程以及消息的分发,在该线程下从 MessageQueue 获取 Message,分发给 Handler。
MessageQueue :是个队列,负责消息的存储与管理,负责管理由 Handler 发送过来的 Message。
Handler : 负责发送并处理消息,⾯向开发者,提供 API,并隐藏背后实现的细节。
Message:final类不可继承, 实现了Parcelable 序列化接⼝,可以在不同进程之间传递。
来看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);
}
/**
* @hide
*/
@UnsupportedAppUsage
public Handler(boolean async) {
this(null, async);
}
/**
* @hide
*/
public Handler(@Nullable Callback callback, boolean async) {
if (FIND_POTENTIAL_LEAKS) {
红外感应水龙头
final Class<? extends Handler> klass = getClass();
if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
(Modifiers() & Modifier.STATIC) == 0) {
Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
}
}
mLooper = Looper();
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;
}
/**
* @hide
*/
@UnsupportedAppUsage
public Handler(@NonNull Looper looper, @Nullable Callback callback, boolean async) {
mLooper = looper;
mQueue = looper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
当我们调⽤handler构造⽅法,都会⾛到最后的两个使⽤@hide注解的⽅法,我们可以看到,初始化了mLooper 和 mQueue。当我们没有构造⽅法中传Looper,会通过 Looper() ⽅法来当前线程绑定的Looper,从这个⽅法⼀层层的往下。
Looper#myLooper
public static @Nullable Looper myLooper() {
();
}
ThreadLocal#get
美容枕
public T get() {
防老剂rdThread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = Entry(this);
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
return setInitialValue();
}
可以看到该⽅法通过ThreadLocal来拿到当前线程绑定的Looper。那么 ThreadLocal在哪⾥和Looper绑定线程呢?Looper#prepare
public static void prepare() {
prepare(true);
}
private static void prepare(boolean quitAllowed) {
if (() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper(quitAllowed));
}
ThreadLocal#set
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
可以看到,通过调⽤ Looper.prepare ⽅法,通过ThreadLocal将当前线程和Looper绑定起来。
然后调⽤Looper#loop
养蜂专用车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;
...
for (;;) {
Message msg = (); // might block
if (msg == null) {
/
/ No message indicates that the message queue is quitting.
槭叶铁线莲return;
}
...
try {
//关键⽅法--------
msg.target.dispatchMessage(msg);
//关键⽅法---------
if (observer != null) {
}
dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0;
} catch (Exception exception) {
if (observer != null) {
observer.dispatchingThrewException(token, msg, exception);
}
微型键盘
throw exception;
} finally {
if (traceTag != 0) {
}
}
}
}
MessageQueue#next
@UnsupportedAppUsage
Message next() {
// Return here if the message loop has already quit and been disposed.
// This can happen if the application tries to restart a looper after quit
// which is not supported.
final long ptr = mPtr;
if (ptr == 0) {
return null;
}
int pendingIdleHandlerCount = -1; // -1 only during first iteration
int nextPollTimeoutMillis = 0;
for (;;) {
if (nextPollTimeoutMillis != 0) {
Binder.flushPendingCommands();
}
nativePollOnce(ptr, nextPollTimeoutMillis);
synchronized (this) {
// Try to retrieve the next message.  Return if found.
final long now = SystemClock.uptimeMillis();
Message prevMsg = null;
Message msg = mMessages;
if (msg != null && msg.target == null) {
if (msg != null && msg.target == null) {
// Stalled by a barrier.  Find the next asynchronous message in the queue.
do {
prevMsg = msg;
msg = ;
} while (msg != null && !msg.isAsynchronous());
}
if (msg != null) {
if (now < msg.when) {
// Next message is not ready.  Set a timeout to wake up when it is ready.
nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);                    } else {
// Got a message.
mBlocked = false;
if (prevMsg != null) {
< = ;
} else {
mMessages = ;
}
< = null;
if (DEBUG) Log.v(TAG, "Returning message: " + msg);
msg.markInUse();
return msg;
}
} else {
// No more messages.
nextPollTimeoutMillis = -1;
}
// Process the quit message now that all pending messages have been handled.
if (mQuitting) {
dispose();
return null;
}
if (pendingIdleHandlerCount < 0
&& (mMessages == null || now < mMessages.when)) {
pendingIdleHandlerCount = mIdleHandlers.size();
}
if (pendingIdleHandlerCount <= 0) {
// No idle handlers to run.  Loop and wait some more.
//关键代码,没有消息就阻塞
mBlocked = true;
continue;
}
if (mPendingIdleHandlers == null) {
mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)];                }
mPendingIdleHandlers = Array(mPendingIdleHandlers);
}
for (int i = 0; i < pendingIdleHandlerCount; i++) {
final IdleHandler idler = mPendingIdleHandlers[i];
mPendingIdleHandlers[i] = null; // release the reference to the handler
boolean keep = false;
try {
keep = idler.queueIdle();
} catch (Throwable t) {
Log.wtf(TAG, "IdleHandler threw exception", t);
}
if (!keep) {

本文发布于:2024-09-23 10:27:32,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/2/277057.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:消息   线程   实现   机制   负责   问到   没有
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议