Android源碼閱讀——Handler機制

Handler機制源碼閱讀

注:這邊文字只是我閱讀源碼的筆記,方便以後查看或者回憶。

  1. Handler機制是什麼?
    Handler是谷歌提供的一條消息處理機制。

  2. Handler幹了什麼?

    1. 我們都知道Handler是維護Handler機制的
    2. 當我們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。我們一起學習,一起進步!

重要的事情說三遍:

  • 學習、掙錢、自由
  • 學習、掙錢、自由
  • 學習、掙錢、自由

疫情當下,唯有自強

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章