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。我們一起學習,一起進步!
重要的事情說三遍:
- 學習、掙錢、自由
- 學習、掙錢、自由
- 學習、掙錢、自由
疫情當下,唯有自強