Handler机制源码阅读
注:这边文字只是我阅读源码的笔记,方便以后查看或者回忆。
-
Handler机制是什么?
Handler是谷歌提供的一条消息处理机制。 -
Handler干了什么?
- 我们都知道Handler是维护Handler机制的
- 当我们new Hanlder会发生什么?
Handler handler=new Handler(); /** * 首先调用了无参的构造方法 */ public Handler() { this(null, false); } /** *this方法调用 *@paramcallback 也就是我们的handleMessage(Message msg)消息回调 *@async 是否异步 **/ public Handler(@Nullable Callback callback, boolean async) { if (FIND_POTENTIAL_LEAKS) { final Class<? extends Handler> klass = getClass(); if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) && (klass.getModifiers() & Modifier.STATIC) == 0) { Log.w(TAG, "The following Handler class should be static or leaks might occur: " + klass.getCanonicalName()); } } 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; }
很需要值得注意的地方:mLooper = Looper.myLooper();
looper是通过Looper.MyLooper()方法获取的
queue 是looper.queue得到的
那Looper.MyLooper()方法是不是进行初始化looper的呢?
/**
* Return the Looper object associated with the current thread. Returns
* null if the calling thread is not associated with a Looper.
*/
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}
????为什么不是初始化looper,而是通过sThreadLocal.get()返回looper?
looper是在哪里初始化的?或者说sThreadLocal是在哪里set 我们的looper的?
搜索整个的looper发现全文只有一次对sThreadLocal.set()的
注:为了方便查看,源码顺序给替换了
private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
#############在这里进行set的 并且new了一个looper
sThreadLocal.set(new Looper(quitAllowed));
}
public static void prepare() {
prepare(true);
}
public static void prepareMainLooper() {
prepare(false);
synchronized (Looper.class) {
if (sMainLooper != null) {
throw new IllegalStateException("The main Looper has already been prepared.");
}
sMainLooper = myLooper();
}
}
也就是说只有调用了prepare(boolean quitAllowed)方法,才会进行sThreadLocal.set 一个looper
那什么时候调用的呢?代码我也贴在上面了 prepare()调用了 prepareMainLooper也调用了。很明显prepareMainLooper是主线程调用的。
在ActivityThread的main方法调用了prepareMainLooper进行主线程初始化looper(这里不贴源码了,大家可以去看一下),当然如果子线程需要初始化looper,我们直接调用Looper.prepare()就ok了。
好的大概的流程我们知道了:
主线程创建——》looper创建——》MessageQueue
注意一点:一个线程只有一个looper
- 其他:
这篇文章没有写完,主要是想给我或者大家自己去看的机会,我是一个健忘的人,如果下次看到了这篇文章,可能就不会再去看一次源码了,所以我留着下次看的时候补齐,谢谢大家。
题外话:谢谢大家观看,有不足之处欢迎大家一起讨论;码字不易,大家喜欢,麻烦点赞哦。
灵魂三问:
- 有没有觉得技术得不到系统的提升,技术成长慢?
- 有没面试懵逼,升职加薪难?
- 有没有想过去大一点的世界看看?
有期望JAVA技术巩固的、Android知识进阶的、期望升职加薪的、Android面试技巧的、大厂面试真题的;大家可以加我QQ哦:1070800492。我们一起学习,一起进步!
重要的事情说三遍:
- 学习、挣钱、自由
- 学习、挣钱、自由
- 学习、挣钱、自由
疫情当下,唯有自强