handler

概述

很多android初学者对android 中的handler不是很明白,其实Google参考了Windows的消息处理机制,

在Android系统中实现了一套类似的消息处理机制。在下面介绍handler机制前,首先得了解以下几个概念:

  1. Message

消息,理解为线程间通讯的数据单元。例如后台线程在处理数据完毕后需要更新UI,则可发送一条包含更新信息的Message给UI线程。

  1. Message Queue

消息队列,用来存放通过Handler发布的消息,按照先进先出执行。

  1. Handler

Handler是Message的主要处理者,负责将Message添加到消息队列以及对消息队列中的Message进行处理。

  1. Looper

循环器,扮演Message Queue和Handler之间桥梁的角色,循环取出Message Queue里面的Message,并交付给相应的Handler进行处理。

  1. 线程

UI thread 通常就是main thread,而Android启动程序时会替它建立一个Message Queue。

每一个线程里可含有一个Looper对象以及一个MessageQueue数据结构。在你的应用程序里,可以定义Handler的子类别来接收Looper所送出的消息。

Handler作用:

因为在Android中,主线程不建议做耗时的操作,子线程不建议跟新UI,但是Android开发,其实就是搭建好页面,将服务器的数据展示到页面上,所以我网络请求使用会非常频繁,而网络请求属于耗时操作,需要放到子线程完成,但一般情况下也不会通过子线程更新UI,需要将请求成功的数据发送到主线程进行UI更新,所以一般会使用到handler。

Handler执行流程:

首先handler作为任务执行者,一般创建在主线程,当子线程有需要发送的数据,通过创建message对象,使用handler对象将消息发送到messagequeue,messagequeue遵循了队列先进先出的原则,当主线程的looper循环消息的时候,会按照messagequeue队列的顺序循环消息,并将消息给到任务执行者handler去执行任务。

Handler执行原理:

Handler创建完成后,内部的Looper以及MessageQueue就可以和Handler一起协同工作,然后通过Hadler的post方法将一个Runnable投递到Handler内部的Looper中去处理,也可以通过Handler的send方法发送一个消息,这个消息会在Looper中做处理。Post最终也是通过send来完成的。当Handler的send方法被调用时,他会调用MessageQueue的enqueueMessage方法将这个消息放入消息队列中,然后Looper发现有新消息到来时,就会处理这个消息,最终消息中的Runnable或者Handler的handlerMessage方法就会被调用。Looper试运行在Handler所在的线程,所以就把业务逻辑切换到主线程了

1.ThreadLocal的工作原理
(1)定义:ThreadLocal是线程内部的数据存储类,通过他可以在指定的线程中存储数据,该数据只有在指定线程中可以获取
(2)使用场景:当某些数据是以线程为作用域并且不同线程具有不同的数据副本的时候另外还可以使用在复杂逻辑下的对象传递,比如监听器的传递
ThreadLoal的值在table数组中的存储位置总是为ThreadLocal的reference字段所标识的对象的下一个位置。ThreasdLoacal的set和get方法所操作的对象都是当前线程的localValues对象的table数组,因此在不同的线程中访问同一个ThreadLocal的set和get方法,他们对ThreadLocal所做的读写操作仅限于各自线程的内部,从而实现在多个线程中互不干扰的存储和修改数据。

Looper的工作原理

Looper在Android的消息机制中扮演着消息循环的角色,就是不停的从MessageQueue中查看是否有新消息,如果有消息就立刻处理,否则就一直阻塞在哪里首先在构造方法中创建一个MessageQueue即队列消息,然后将当前的对象保存起来Looper除了prepare方法外,还提供了prepareMainLooper方法,这个方法主要是给主线程也就是ActivityThread创建Looper使用的,其本质也是通过prepare方法来实现的。由于主线程的Looper比较特殊,所以Looper提供了一个getMainLooper方法,通过它可以再任何地方获取到主线程的Looper。Looper也是可以退出的,Looper提供了quit和quitSafely来退出一个Looper,二者的区别是:quit会直接退出Looper,而quieSafely只是假定一个特殊标记,然后把消息队列中的已有消息处理完毕后才安全退出。Looper退出后,通过Handler发送消息失败,这个时候Handler的send方法会返回false。在子线程中,如果手动为其创建Looper,那么在所有的事情完成以后应该调用quit方法来终止消息循环,否则这个子线程就会一直处于等待状态,而如果想退出Looper以后,这个线程就会立刻终止,,因此建议不需要的时候终止Looperloop方法是个死循环,唯一跳出循环的方式是MessageQueue的next方法返回null。当Looper的quit方法被调用时,Looper就会调用MessageQueue的quit或者quitSafely方法来通知消息队列退出,当消息队列被标记为退出状态时,它的next方法就返回null。Loop必须退出,否则loop循环就会无限循环下去。loop方法会调用MessageQueue的next方法,而next方法是一个当没有消息时 是一个阻塞线程,便会导致Looper也会阻塞在那里。当MessageQueue的next方法返回了新的消息,Looper就会处理这条消息:msg.target.disapatchMessage,这里msg.target是发送这条消息的Handler对象,消息交给dispatchMessage方法来处理。而这个dispatchMessage方法是在创建Handler时所用的Looper中执行。这样就把代码逻辑切换到主线程。

主线程向子线程发送消息:

首先handler肯定是要创建到子线程当中,用于接收主线程发来消息进行处理,但是,因为子线程没有looper对象,首先需要调用looper.prepare(),当主线程发来消息后,已经准备好的looper同样会去消息队列当中循环消息,交给handler,但handler真正能够使用该数据还得调用looper.loop();

Measge可以通过wait来区分消息
Mesage通过takte来区分handler

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,718评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,683评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,207评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,755评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,862评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,050评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,136评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,882评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,330评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,651评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,789评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,477评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,135评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,864评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,099评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,598评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,697评论 2 351