Handle通信机制

Handle通信机制

一、大致流程

1.在创建Activity之前,应用启动时会加载ActivityThread这个类,这个类就是我经常说的UITherad(主线程),在main()方法中调用Looper(轮询器)的prepareMainLooper()方法,为主线程绑定一个Looper对象。在绑定Looper对象的时候,在Looper的构造函数中创建了一个MessageQueue(消息队列)对象。然后再调用Looper.loop()方法,开启循环。

ActivityThread中的代码:

  public static final void main(String[] args) {
        SamplingProfilerIntegration.start();

        Process.setArgV0("<pre-initialized>");

        Looper.prepareMainLooper();//绑定一个轮询器
        if (sMainThreadHandler == null) {
            sMainThreadHandler = new Handler();
        }

        ActivityThread thread = new ActivityThread();
        thread.attach(false);

        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }

        Looper.loop();//开启轮询

        if (Process.supportsProcesses()) {
            throw new RuntimeException("Main thread loop unexpectedly exited");
        }

        thread.detach();
        String name = (thread.mInitialApplication != null)
            ? thread.mInitialApplication.getPackageName()
            : "<unknown>";
        Slog.i(TAG, "Main thread of " + name + " is now exiting");
    }
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));
    }

    /**
     * Initialize the current thread as a looper, marking it as an
     * application's main looper. The main looper for your application
     * is created by the Android environment, so you should never need
     * to call this function yourself.  See also: {@link #prepare()}
     */
    public static void prepareMainLooper() {
        prepare(false);
        synchronized (Looper.class) {
            if (sMainLooper != null) {
                throw new IllegalStateException("The main Looper has already been prepared.");
            }
            sMainLooper = myLooper();
        }
    }

2.创建Handle,在Handler的构造函数中获取主线程绑定的Looper对象,再从Looper对象中获取MessageQueue对象。

public Handler() {
     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();// 获得当前线程绑定的looper对象
     if (mLooper == null) {
         throw new RuntimeException(
                "Can't create handler inside thread that has not called Looper.prepare()");
     }
     mQueue = mLooper.mQueue;// 获得Looper中创建出来的 messageQueue对象
     mCallback = null;
}

3.发送消息,调用sendMessageAtTime(Message msg, long uptimeMillis)方法(其他发送消息的方法都是重载这个方法)。通过MessageQueue对象的enqueueMessage(msg, uptimeMillis)方法,把Message(消息对象)添加到消息队列中。

public boolean sendMessageAtTime(Message msg, long uptimeMillis)
    {
        boolean sent = false;
        MessageQueue queue = mQueue;// 获得消息对队
        if (queue != null) {
            msg.target = this;// 消息的目标就是 当前 handler  对象
            sent = queue.enqueueMessage(msg, uptimeMillis);
        }
        else {
            RuntimeException e = new RuntimeException(
                this + " sendMessageAtTime() called with no mQueue");
            Log.w("Looper", e.getMessage(), e);
        }
        return sent;
    }

4.Looper循环已经开启,用一个无限循环从消息队列中取消息,如果没有消息就等待,直到取到消息。当轮询器取到消息的时候,再通过Message对象的target(在发送消息的时候把当前的Handle对象赋值给target,它就是当前的Handle)调用Handle的dispatchMessage(Message msg)方法。在这个方法中执行了handleMessage(msg)方法。

Looper中的方法:

public static final void loop() {
        Looper me = myLooper();// 获得当前looper 对象
        MessageQueue queue = me.mQueue;// 获得消息队列
        while (true) {
            Message msg = queue.next();// 从消息对队中取出一个消息 ,如果没有消息,就等待,有消息有时候,再取
            if (msg != null) {
                if (msg.target == null) {
                    // No target is a magic identifier for the quit message.
                    return;
                }
                if (me.mLogging!= null) me.mLogging.println(
                        ">>>>> Dispatching to " + msg.target + " "
                        + msg.callback + ": " + msg.what
                        );
                msg.target.dispatchMessage(msg);// 就是执行 handler.handleMessage(msg)方法
                if (me.mLogging!= null) me.mLogging.println(
                        "<<<<< Finished to    " + msg.target + " "
                        + msg.callback);
                msg.recycle();// 释放,以便于下次利用
            }
        }
    }
Handle中的方法:

    /**
     * Handle system messages here.
     */
    public void dispatchMessage(Message msg) {
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg);
        }
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值