美文网首页
Handler源码分析

Handler源码分析

作者: 左上偏右 | 来源:发表于2016-11-20 18:00 被阅读18次
    Paste_Image.png

    Handler

    Handler:负责发送和接收消息

    1、创建Handler时调用的它的构造函数Handler(null,false),主要获取当前线程的Looper对象和消息循环。

        public Handler(Callback callback, boolean async) {
            mLooper = Looper.myLooper();
            mQueue = mLooper.mQueue;
            mCallback = callback;
            mAsynchronous = async;
        }
    
    2、发送消息sendMessage
    • sendMessage方法,发送消息最终调用的是Handler中的enqueueMessage方法,MessageQueue中的enqueueMessage方法,在消息队列中通过msg.when将消息放到合适的位置。
    private boolean enqueueMessage(MessageQueue queue, Message msg,
    long uptimeMillis) {
            msg.target = this;
            if (mAsynchronous) {
                msg.setAsynchronous(true);
            }
            return queue.enqueueMessage(msg, uptimeMillis);
    }
        ```
    * obtainMessage方法,它是从消息池里面取出一个消息,没有时才创建消息效率高。
        
    * postDelayed方法,此方法需要传一个Runnable对象,最终赋值给Message的callback属性。
    

    private static Message getPostMessage(Runnable r) {
    Message m = Message.obtain();
    m.callback = r;
    return m;
    }

    ######3、分发消息dispatchMessage
    

    public void dispatchMessage(Message msg) {
    //如果callback不为空,直接调用
    if (msg.callback != null) {
    message.callback.run();
    handleCallback(msg);
    } else {
    //创建Handler时,传递的Callback接口,默认为null。
    if (mCallback != null) {
    if (mCallback.handleMesscage(msg)) {
    return;
    }
    }
    handleMessage(msg);//回调子类方法,在Handler类里面只是声明。
    }
    }

    ###Looper:
    * 1、ThreadLocal类
        它的作用是为每一个线程保存一份变量,内部其实用一个数组来表示,对索引进行散列保证内部均匀。
        >ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
        
    * 2、prepare方法准备操作
        准备Looper类,在Looper构造函数里面创建消息队列和获取当前线程。将线程和Looper进行关联起来。
    
    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));
    }
    private Looper(boolean quitAllowed) {
        mQueue = new MessageQueue(quitAllowed);
        mThread = Thread.currentThread();
    }
    
    * 3、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;
        for (;;) {
            Message msg = queue.next(); // might block
            if (msg == null) {
                return;// No message indicates that the message 
            }
            msg.target.dispatchMessage(msg);//消息分发
            msg.recycle();//回收消息
        }
    }
    
        
    ###Message:
    * 属性target
    发送消息时将消息的target属性设置为this(就是Handler),在通过msg.target.dispatchMessage方法可以找到发送消息的Handler。
        
    ###MessageQueue:
    *  1、获取消息
        queue.next(),通过msg.when进行计算出合适的Message.
        
        
    ###ActivityThread
        
    Android程序入口函数是ActivityThread的main函数,在这里先调用Looper.prepareMainLooper方法,创建ActivityThread.
    

    final ApplicationThread mAppThread = new ApplicationThread();
    private void attach(boolean system) {
    if (!system) {
    RuntimeInit.setApplicationObject(mAppThread.asBinder());
    final IActivityManager mgr = ActivityManagerNative.getDefault();
    mgr.attachApplication(mAppThread);
    } else {
    android.ddm.DdmHandleAppName.setAppName("system_process",
    UserHandle.myUserId());
    mInstrumentation = new Instrumentation();
    ContextImpl context = ContextImpl.createAppContext(this,
    getSystemContext().mPackageInfo);
    mInitialApplication = context.mPackageInfo.makeApplication(true, null);
    mInitialApplication.onCreate();
    }
    }

    
    

    public static void main(String[] args) {
    //创建
    Looper.prepareMainLooper();
    ActivityThread thread = new ActivityThread();
    thread.attach(false);
    //
    if (sMainThreadHandler == null) {
    sMainThreadHandler = thread.getHandler();
    }
    Looper.loop();
    }

    相关文章

      网友评论

          本文标题:Handler源码分析

          本文链接:https://www.haomeiwen.com/subject/uldypttx.html