此文章是vip文章,如何查看?  

1,点击链接获取密钥 http://nicethemes.cn/product/view29882.html

2,在下方输入文章查看密钥即可立即查看当前vip文章


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。我们一起学习,一起进步!

重要的事情说三遍:

  • 学习、挣钱、自由
  • 学习、挣钱、自由
  • 学习、挣钱、自由

疫情当下,唯有自强

本文链接http://element-ui.cn/news/show-692931.aspx