• Handle/Looper源码分析;


    1. Handle中的属性:

        final Looper mLooper;
        final MessageQueue mQueue;
        final Callback mCallback;
        final boolean mAsynchronous;
        IMessenger mMessenger;

       mQueue消息队列,拥有消息队列的引用,handle可以对已发送的消息或任务再进行取消操作,如下源码:

      public final void removeMessages(int what) {
      mQueue.removeMessages(this, what, null);
      }
      public final void removeMessages(int what, Object object) {
            mQueue.removeMessages(this, what, object);
        }
    
        /**
         * Remove any pending posts of callbacks and sent messages whose
         * <var>obj</var> is <var>token</var>.  If <var>token</var> is null,
         * all callbacks and messages will be removed.
         */
        public final void removeCallbacksAndMessages(Object token) {
            mQueue.removeCallbacksAndMessages(this, token);
        }

    往消息队列中添加消息:

        private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
            msg.target = this;         //Message中记录了来自哪个handle
            if (mAsynchronous) {
                msg.setAsynchronous(true);
            }
            return queue.enqueueMessage(msg, uptimeMillis);
        }

    2.Handle中的初始化:

      通常我们使用的方式是 Handle handle=new Handle();这一过程执行的代码是:

      

       public Handler(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 that has not called Looper.prepare()");
            }
            mQueue = mLooper.mQueue;
            mCallback = callback;
            mAsynchronous = async;
        }

      可以看出  ,这里在Looper中拿到looper和MessageQueue的引用赋值给Handler中的变量,MessageQueue和Looper的创建是在looper中完成的。

    3.Looper:

      1)主要的属性:

    static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
    private static Looper sMainLooper;  // guarded by Looper.class
    final MessageQueue mQueue;
    final Thread mThread;

      2)构造函数:

      对MessageQueue和mThread进行了初始化

        private Looper(boolean quitAllowed) {
            mQueue = new MessageQueue(quitAllowed);
            mThread = Thread.currentThread();
        }

      3)prepare()方法:中对Looper进行了构建;并存放在ThreadLocal中。

        private static void prepare(boolean quitAllowed) {
            if (sThreadLocal.get() != null) {
                throw new RuntimeException("Only one Looper may be created per thread");
            }
            sThreadLocal.set(new Looper(quitAllowed));
        }

       ※static final ThreadLocal<Looper> 可知线程本地变量是静态final 类型的 整个进程中只有一份,里面存储 各个线程的Looper,存储方式类似于键(thread)值(looper)的方式。

      4)looper():

        

       /**
         * Run the message queue in this thread. Be sure to call
         * {@link #quit()} to end the 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;
    
            // Make sure the identity of this thread is that of the local process,
            // and keep track of what that identity token actually is.
            Binder.clearCallingIdentity();
            final long ident = Binder.clearCallingIdentity();
    
            for (;;) {
                Message msg = queue.next(); // might block
                if (msg == null) {
                    // No message indicates that the message queue is quitting.
                    return;
                }
    
                // This must be in a local variable, in case a UI event sets the logger
                final Printer logging = me.mLogging;
                if (logging != null) {
                    logging.println(">>>>> Dispatching to " + msg.target + " " +
                            msg.callback + ": " + msg.what);
                }
    
                final long traceTag = me.mTraceTag;
                if (traceTag != 0 && Trace.isTagEnabled(traceTag)) {
                    Trace.traceBegin(traceTag, msg.target.getTraceName(msg));
                }
                try {
                    msg.target.dispatchMessage(msg);
                } finally {
                    if (traceTag != 0) {
                        Trace.traceEnd(traceTag);
                    }
                }
    
                if (logging != null) {
                    logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
                }
    
                // Make sure that during the course of dispatching the
                // identity of the thread wasn't corrupted.
                final long newIdent = Binder.clearCallingIdentity();
                if (ident != newIdent) {
                    Log.wtf(TAG, "Thread identity changed from 0x"
                            + Long.toHexString(ident) + " to 0x"
                            + Long.toHexString(newIdent) + " while dispatching to "
                            + msg.target.getClass().getName() + " "
                            + msg.callback + " what=" + msg.what);
                }
    
                msg.recycleUnchecked();
            }
        }

        这里有个循环 不断监控mQueue中的消息,有消息了 就取出 交给Handle处理;

      5)。Thread TheadLocal  ThreadLocalMap;

        ThreadLocalMap是TheadLocal的内部类,ThreadLocalMap是Thread的成员变量;Loop.prepare()里面,ThreadLocal负责将Looper对象存储到Thread的ThreadLocalMap中;

    主线程的Looper初始化:

      源码的位置是在ActivityThread类中的main函数。

      

    public static void main(String[] args) {  
            SamplingProfilerIntegration.start();  
            CloseGuard.setEnabled(false);  
            Environment.initForCurrentUser();  
            // Set the reporter for event logging in libcore  
            EventLogger.setReporter(new EventLoggingReporter());  
            Process.setArgV0("<pre-initialized>");  
            Looper.prepareMainLooper();//这实际就是一个实例化一个looper对象,大家也可以看看prepareMainlooper方法(下方)。  
            ActivityThread thread = new ActivityThread();  
            thread.attach(false);  
            if (sMainThreadHandler == null) {  
                sMainThreadHandler = thread.getHandler();  
            }   
        Looper.loop();//启动循环器   
    }  
    

      

  • 相关阅读:
    DELPHI SOKET 编程(使用TServerSocket和TClientSocket)
    DELPHI 任务栏无EXE显示
    Delphi 实现无窗口移动(详细使用WM_NCHITTEST和PtInRect API进行测试)
    ViewPager的简单使用
    delphi 网页提交按钮执行点击事件
    Delphi 获取网站验证码的图片
    Delphi 模拟网站验证码(酷,把随机文字写道图片上)
    张文木的文章都很不错,有空仔细看看
    深度RAMOS,把操作系统全部安装在内存上
    C# ASP.net 入门之简单通讯录
  • 原文地址:https://www.cnblogs.com/xxwn/p/7744815.html
Copyright © 2020-2023  润新知