Android Message handling (based on KK4.4)
一、几个关键概念
1、MessageQueue:是一种数据结构,见名知义,就是一个消息队列。存放消息的地方。每个线程最多仅仅能够拥有一个MessageQueue数据结构。
创建一个线程的时候,并不会自己主动创建其MessageQueue。通常使用一个Looper对象对该线程的MessageQueue进行管理。主线程创建时。会创建一个默认的Looper对象,而Looper对象的创建,将自己主动创建一个Message Queue。
其它非主线程,不会自己主动创建Looper,要须要的时候。通过调用prepare函数来实现。
2、Message:消息对象,Message Queue中的存放的对象。一个Message Queue中包括多个Message。
Message实例对象的取得,通常使用Message类里的静态方法obtain(),该方法有多个重载版本号可供选择。它的创建并不一定是直接创建一个新的实例,而是先从Message Pool(消息池)中看有没有可用的Message实例。存在则直接取出返回这个实例。假设Message Pool中没有可用的Message实例,则才用给定的參数创建一个Message对象。调用removeMessages()时,将Message从Message Queue中删除,同一时候放入到Message Pool中。除了上面这样的方式。也能够通过Handler对象的obtainMessage()获取一个Message实例。
3、Looper:
是MessageQueue的管理者。每个MessageQueue都不能脱离Looper而存在。Looper对象的创建是通过prepare函数来实现的。同一时候每个Looper对象
和一个线程关联。通过调用Looper.myLooper()能够获得当前线程的Looper对象
创建一个Looper对象时,会同一时候创建一个MessageQueue对象。除了主线程有默认的Looper,其它线程默认是没有MessageQueue对象的。所以。不能接受Message。
如须要接受。自定义一个Looper对象(通过prepare函数),这样该线程就有了自己的Looper对象和MessageQueue数据结构了。
Looper从MessageQueue中取出Message然后。交由Handler的handleMessage进行处理。处理完毕后,调用Message.recycle()将其放入Message Pool中。
4、Handler:
消息的处理者。handler负责将须要传递的信息封装成Message。通过调用handler对象的obtainMessage()来实现;
将消息传递给Looper。这是通过handler对象的sendMessage()来实现的。
继而由Looper将Message放入MessageQueue中。
当Looper对象看到MessageQueue中含有Message,就将其广播出去。该handler对象收到该消息后,调用对应的handler对象的handleMessage()方法对其进行处理。
Handler会关联一个单独的线程和消息队列。Handler默认关联主线程,尽管要提供Runnable參数 ,但默认是直接调用Runnable中的run()方法。也就是默认下会在主线程运行,假设在这里面的操作会有堵塞。界面也会卡住。假设要在其它线程运行,能够使用HandlerThread
自己的总结looper相当于MessageQueue的创建者以及管理员。而 Handler为处理者,处理MessageQueue两端的事务。
每个线程都有一个looper,
looper拥有一个message queue
looper是一个死循环。不停处理message queue中的消息。
handler是方便多线程处理或异步处理而创建的数据结构,
它拥有两个成员,一个指向handler被创建的线程的looper,一个是该线程的消息队列。
所以,调用handler的post方法,实际上是把消息放到了该线程的消息队列(注意。不是当前线程,假设你在主线程中创建的handler,在子线程中调用handler的post方法,实际上是把消息发送到主线程的消息队列)(自己加的“post到handler被创建的地方,即handler所属的地方”);每个消息有一个target成员。handler发送过去的消息会把该消息的target设置称为自己。
looper收到消息后会处理。而且把消息发送给target,也就是说消息转了一圈又回到了handler。handler能够做出理。
这个过程看似绕道,实际上非常有必要。调用handler post是在子线程中。而handler的处理方法是在主线程中被调用的,这个过程伴随一次线程调度的。
HandlerThread是继承Thread,基本的作用是建立了一个线程。而且创立了消息队列,有来自己的looper,能够让我们在自己的线程中分发和处理消息。
android的消息处理通过handler和looper, HandlerThread不但能提供异步处理,Handler处理消息的方法也会在这个线程中运行,他最要的作用就是提供了一个线程。http://www.eoeandroid.com/thread-193224-1-1.html
要使用Looper才干建立Android的消息机制。Thread的确是能够自己通过代码来实现HandlerThread的功能,但你看HandlerThread的API介绍:Handy class for starting a new thread that has a looper. The looper can then be used to create handler classes. Note that start() must still be called.能够说它本身就是个简化须要实现消息机制的Thread类代码的类。帮你把一些必要的代码都已经写好了。另外重写它的onLooperPrepared方法能够帮你做一些Looper開始loop之前的初始化工作,代码更加清晰。
Android Message handling (based on KK4.4)的更多相关文章
- Android Message Handling Mechanism
转自:http://solarex.github.io/blog/2015/09/22/android-message-handling-mechanism/ Android is a message ...
- [Android]Message,MessageQueue,Looper,Handler详解+实例
转http://www.eoeandroid.com/forum-viewthread-tid-49595-highlight-looper.html 一.几个关键概念 1.MessageQueue: ...
- Android Message里传送的数据[转]
package org.hualang.handlertest; import android.app.Activity; import android.os.Bundle; import andro ...
- Android Message和obtainMessage的区别
类概述 定义一个包含任意类型的描述数据对象,此对象可以发送给Handler.对象包含两个额外的int字段和一个额外的对象字段,这样可以使得在很多情况下不用做分配工作. 尽管Message的构造器是公开 ...
- [转]Android Message.obtain() 和Handler.obtainMessage()的区别
目录(?)[+] 参考:http://www.2cto.com/kf/201311/255885.html http://www.cnblogs.com/over140/archive/2 ...
- Android Message和obtainMessage的差别
前几天须要实现一个以太网功能就看了以太网的源代码部分,看见了源代码部分在消息处理时,发现有一些不同的地方: 平时我在处理消息时: 1.首先创建Handler对象: private Hand ...
- Android源码分析之Message
准备开始写点东西,算是对自己阅读源码的一个记录/笔记,也希望能对同样感兴趣的人有所帮助,希望能坚持下去,加油. 在Android的开发中,我们经常用到Handler.postXXX方法,或者View. ...
- TAxThread - Inter thread message based communication - Delphi
http://www.cybletter.com/index.php?id=3 http://www.cybletter.com/index.php?id=30 Source Code http:// ...
- android之handler obtainmessge与New message区别
obtainmessage()是从消息池中拿来一个msg 不需要另开辟空间new new需要重新申请,效率低,obtianmessage可以循环利用: //use Handler.obtainMess ...
随机推荐
- HTML5 Canvas 描画渐开线
渐开线(evolent):在平面上,一条动直线(发生线)沿着一个固定的圆(基圆)作滚动的过程中,此直线上任意一点的轨迹,称为此基圆的一条渐开线.如果将一个圆轴固定在一个平面上,轴上缠线,拉紧一个线头, ...
- 如何Tomcat注册成系统服务
1.开始->运行(windos+r)中敲cmd,DOS界面2.cd到tomcat的bin目录下3.运行命令service.bat install 这里可以指定注册服务的名字,然后就可以 ...
- Google Chrome 35 Released – Install on RHEL/CentOS 6 and Fedora 20-15
Google Chrome is a freeware web browser developed by Google Inc. Google Chrome team proudly announce ...
- 在 Linux 系统下使用 PhotoRec & TestDisk 工具来恢复文件
当你在系统中有意或无意地使用 shift + delete 组合键.删除选项,或是清空回收站的方式来删除一个文件时,该文件的内容并没有从硬盘(或是其它存储设备)上直接销毁. 它仅仅是从系统的目录结构中 ...
- PHP面试题及答案解析(2)—PHP面向对象
1. 写出 php 的 public.protected.private 三种访问控制模式的区别. public:公有,任何地方都可以访问protected:继承,只能在本类或子类中访问,在其它地方不 ...
- C#中的里氏替换原则
里氏转换原则 子类可以赋值给父类对象 父类对象可以强制转化为对应的子类对象 里氏替换原则直观理解就是"子类是父类",反过来就说不通了. 就像男人是人对的,但人是男人就不对了. 这样 ...
- JAVA、Android与Cordova环境搭建
一些坑(如Manager.exe闪退的问题)请查看:https://www.cnblogs.com/CyLee/p/9911195.html 官方网址: # Cordova http://cordov ...
- gitlab配置smtp时,总是提示需要鉴权,记录一下爬坑过程。
配置好smtp,然后发送邮件时总是提示 Net::SMTPFatalError: 550 5.7.1 authentication is required 最后发现是因为在gitlab web界面上配 ...
- Pig系统分析(7)-Pig有用工具类
Explain Explain是Pig提供的调试工具,使用explain能够输出Pig Lation的运行计划.值得一提的是,explain支持-dot选项.将运行计划以DOT格式输出, (DOT是一 ...
- Ubuntu14下Hadoop开发<1> 基础环境安装
准备了一台淘汰的笔记本.单核CPU.3G内存.160G硬盘:准备一个2G的U盘 在官网下载了64位的14.04版本号(麒麟)的ISO.下载UNetbootin(Ubuntu专用U盘安装工具) 使用UN ...