美文网首页
深入理解Android消息机制(一)初识

深入理解Android消息机制(一)初识

作者: 怡红快绿 | 来源:发表于2019-05-20 11:47 被阅读0次

    本系列相关阅读


    Android的消息机制主要是指Handler运行机制。由于Android开发规范明确表示只能在主线程更新UI,因此当子线程完成工作,我们需要使用Handler切换到主线程执行UI更新操作。

    Handler的使用方式非常简单,我们只需要在主线程中创建Handler对象并重写handleMessage方法:

    final SafeHandler safeHandler = new SafeHandler(this);
    
    private static class SafeHandler extends Handler {
    
        private WeakReference<Context> contextWeakReference;
    
        public SafeHandler(Context context) {
            this.contextWeakReference = new WeakReference<>(context);
        }
    
        @Override
        public void handleMessage(Message msg) {
            if (contextWeakReference != null) {
                Context context = contextWeakReference.get();
                if (context != null) {
                    //更新UI操作
                    switch (msg.what) {
                        case 0:
                            Toast.makeText(context, "更新UI", Toast.LENGTH_SHORT).show();
                            break;
                        case 1:
                            break;
                        default:
                            break;
                    }
                }
            }
            super.handleMessage(msg);
        }
    }
    

    然后在子线程中就可以发送消息提醒主线程更新UI:

    new Thread(new Runnable() {
        @Override
        public void run() {
            safeHandler.sendEmptyMessage(0);//子线程通知主线程更新UI
        }
    }).start();
    

    Handler之所以能如此便捷地实现线程间的消息传递,当然离不开底层的MessageQueueLooper的支持。

    简单介绍一下它们:

    • MessageQueue 消息队列
      用来缓存一系列待处理的消息,它的内部存储结构并不是真正的队列,而是采用单链表结构来存储消息列表。
    • Looper 循环
      MessageQueue不能处理消息,这个工作由Looper来完成。它是以无限循环的形式去询问是否有新消息,如果有的话就处理,如果没有就一直等待。
    • ThreadLocal
      一个线程内部的数据存储类,通过它可以在 指定的线程中存储数据,数据存储以后,只有在指定线程中可以获取到存储的数据,对于其他线程来说则无法获取到数据。【这是一篇详细介绍ThreadLocal的文章,点击查看】

    我们知道,Handler在创建的时候会采用当前线程的Looper来构建消息循环系统,那么它是如何获取到当前线程的Looper的?答案就是使用ThreadLocal,通过ThreadLocal可以轻松获取每个线程的Looper。如果想继续了解如何获取线程Looper点击深入理解Android消息机制(三)原理分析

    有一点我们要注意:线程在默认情况下是没有Looper的,如果需要使用Handler就必须为线程创建Looper,否则系统会抛出异常 Can't create handler inside thread that has not called Looper.prepare()。根据我们的开发经验,Android中的主线程是可以直接使用Handler的,因为系统在创建ActivityThread的时候会为主线程初始化Looper。

    总结:本文简单地介绍一些消息机制基本概念,顺带着演示了Handler使用步骤,目的就是为了让大家对消息机制有个大致的了解,下一篇会介绍消息机制的具体流程。

    下一篇:深入理解Android消息机制(二)Handler工作过程

    参考

    相关文章

      网友评论

          本文标题:深入理解Android消息机制(一)初识

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