#Android 消息机制handler详细攻略+源码解析

#Android 消息机制handler详细攻略+源码解析

Android 消息机制handler快速攻略,相信读者开发中都遇到过,Android建议不要在主线程中进行耗时操作,否则会导致程序无法响应即ANR.还有网络访问,我们需要从服务端拉取一些信息并将其显示在UI上,这个时候必须在子线程中进行拉取工作,获取数据完毕后又不能在子线程中直接访问UI,如果没有Handler,那么我们的确没有办法将访问的UI工作切换到主线程中去执行.因此,系统之所以提供Handler,主要原因就是为了解决在子线程中无法访问UI的矛盾.在这之前我们需要了解下面几个知识点

  • 安卓线程安全问题: 如果多个线程并发的操作UI组件,是可能导致线程的安全问题出现(如果加上锁机制,2缺点:一逻辑复杂化,二锁机制降低UI访问效率)

  • 解决线程安全: 安卓提供解决的机制,只允许在UI主线程做组件修改

  • 什么是UI主线程: 应用第一次启动时,系统默认启动一条UI线程(也称之为:主线程),专门负责处理UI相关的event

  • 怎么在新线程修改UI组件: 这时候就需要使用Android中提供的一种异步回调机制Handler

一 消息队列(MessageQueue)的工作原理

消息队列在Android中指的是MessageQueue,MessageQueue主要包含两个操作:插入和读取.读取操作本很会伴随着删除操作,插入和读取对应的方法分别为恩enqueueMessage和next,其中enqueueMessage的作用是往消息队列中插入一条消息,而next的作用是从消息队列中取出一条消息并将其从消息队列中移除.尽管MessageQueue叫消息队列,但是它的内部实现并不是用的队列,实际上它是通过一个单链表的数据结构来维护消息列表,单链表在插入和删除上比较有优势.

下面主要看一下它的enqueueMessage和next方法的实现
#Android 消息机制handler详细攻略+源码解析_第1张图片
#Android 消息机制handler详细攻略+源码解析_第2张图片
enqueueMessage的实现来看,他的主要才做其实就是单链表的插入操作.

下面是next主要逻辑如下所示
#Android 消息机制handler详细攻略+源码解析_第3张图片
#Android 消息机制handler详细攻略+源码解析_第4张图片
#Android 消息机制handler详细攻略+源码解析_第5张图片
可以发现next方法是一个无限循环的方法,如果消息队列中没有消息,那么next方法会一直阻塞在这里.当有新消息到来时,next方法会返回这条消息并将其从单链表中移除.

二 Looper的工作原理

Looper在Android的消息机制中扮演着消息循环的角色,它会不停地从MessageQueue中查看是否有新消息,如果有新消息就会立刻处理,否则就一直阻塞在那里.它的构造方法,会创建一个MessageQueue即消息队列,然后将当期线程的对象保存起来

#Android 消息机制handler详细攻略+源码解析_第6张图片
其次,通过Looper.prepare()即可为当前线程创建一个Looper,接着通过Looper.loop()来开启消息循环
#Android 消息机制handler详细攻略+源码解析_第7张图片

Looper的loop方法的工作过程比较好理解,loop方法是一个死循环,唯一跳出循环的方式是MessageQueue的next方法返回了null.当Looper的quit方法被调用时,Looper就会调用MessageQueue的quite或者quitSafely方法来通知消息队列退出,当消息队列被标记为退出状态时,它的next方法就会返回null.也就是说,Looper必须退出,否则loop方法就会无限循环下去.

三 Handler的工作原理

Handler的工作主要包含消息的发送和接收过程.消息的发送可以通过post的系列方法以及send的系列方法来实现,post的系列方法最终是通过sed的一系列方法来实现的.
#Android 消息机制handler详细攻略+源码解析_第8张图片
#Android 消息机制handler详细攻略+源码解析_第9张图片
#Android 消息机制handler详细攻略+源码解析_第10张图片

#Android 消息机制handler详细攻略+源码解析_第11张图片

从上面可以发现,Handler发送消息的过程仅仅是向消息队列中插入了一条消息,MessageQueue的next方法就会返回这条消息给Looper,Looper收到消息后就开始处理了,最终消息由Looper交由Handler处理,即Handler的diapatchMessage方法会被调用,这是Handler就进入了处理消息的阶段

Handler处理消息的过程可以归纳为一个流程图.

#Android 消息机制handler详细攻略+源码解析_第12张图片

四 ThreadLocal的工作原理

这个ThreadLocal相信不少读者很少接触到,日常开发汇总用到ThreadLocal的地方较少,ThreadLocal是一个线程内部的数据存储类,通过它可以在指定的线程中存储数据,数据存储后,只有在指定线程中获取到存储的数据,对于其他线程来说则无法获取到数据.但是在某些特殊的场景下,通过ThreadLocal可以轻松地实现一些看起来很复杂的功能,在Android的源码种有所体现,比如Looper,ActivityThread以及AMS中都用到了ThreadLocal.

五 例子:轮循器使用

上线项目用到地方举例:
1,在一个教育学习项目中,作业的定时上报成绩,把内存缓存中的学生成绩上报
2,VR教学中控项目,实时刷新补抓VR状态

核心代码部分:

	public void init(){
 		//开始刷状态数据
        mHandler.post(runnable);
  }

    //5秒
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            mHandler.postDelayed(runnable, 10 * 1000);
            Message message = new Message();
            message.what = 1;
            mHandler.sendMessage(message);
        }
    };


    public Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 1:
                   //todo
                    break;
            }
        }
    };

//用完回收
   @Override
    public void onDestroy() {
        super.onDestroy();
	    mHandler.removeCallbacks(runnable);
    }

尾言

为自己技术增值,量变引起质变.对象亦来源于生活,模式亦来源于验证的OO经验,那么请学会使用轮子,再到感受制造轮子的乐趣,你会发现原来编程那么美妙.如有错误或不当之处,请读者留言,博主好吸取经验,互相交流学习,如果本文对你有帮助请帮博主点赞,发注一波,谢谢善良的读者

你可能感兴趣的:(Android,安卓handler,安卓消息机制,什么是handler,handler轮循器)