android学习11——Handler,Looper,MessageQueue工作原理
Message是Handler接收和处理的消息对象. 每个线程只能拥有一个Looper.它的loop方法读取MessageQueue中的消息,读到消息之后就把消息交给发送该消息的Handler进行处理.MessageQueue是消息队列,它采用先进先出的方式来管理Message.程序创建Looper对象时会在它的构造器中创建MessageQueue对象.
下面用一个例子说明.不能在主线程中执行耗时的工作,否则会报ANP错误.常用的方法是在主线程中向子线程中发消息,交给子线程处理.看下面的例子.
public class SumThread extends Thread {
    private Handler handler;
    private Context context;
    public SumThread(Context context) {
        this.context = context;
    }
    @Override
    public void run() {
        Log.i("Logzy", "Loop prepare");
        Looper.prepare();
        handler = new SumHandler(context);
        Looper.loop();
        Log.i("Logzy", "Loop end");
    }
    public Handler getHandler() {
        return handler;
    }
}
在子线程中创建一个Handler.注意在子线程中创建Handler的时候,要先创建Looper对象,并通过prepaer启动它. Looper.loop()是一个死循环,不断从MessageQueue中取出消息交给Handler处理.所以除非显式退出Looper,Log.i("Logzy", "Loop end")这行代码不会被执行.另外需要注意的一点是在主线程中,系统已经初始化一个Looper对象,因此程序直接创建Handler即可,然后就可通过Handler来发送,处理消息.主线程中创建Handler的方法见这个例子http://www.cnblogs.com/zhouyang209117/p/5108048.html
例子的源代码:https://github.com/zhouyang209117/AndroidTutorial/tree/master/Crazy/ch3/Loop
再说HandlerThread的用法.上面已经提到子线程中创建Handler的时候,要先创建Looper对象,并通过prepaer启动.HandlerThread可以将这些操作简化.看下面代码:
public class MyActivity extends Activity {
    static final String UPPER_NUM = "upper";
    EditText etNum;
    private Handler handler;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        etNum = (EditText)findViewById(R.id.etNum);
        HandlerThread handlerThread = new HandlerThread("aaa");
        handlerThread.start();
        handler = new SumHandler(this, handlerThread.getLooper());
    }
    public void cal(View source) {
        Message msg = new Message();
        msg.what = 0x123;
        Bundle bundle = new Bundle();
        bundle.putInt(UPPER_NUM,
                Integer.parseInt(etNum.getText().toString()));
        msg.setData(bundle);
        handler.sendMessage(msg);
    }
}
最重要的是这3行代码:
HandlerThread handlerThread = new HandlerThread("aaa");
handlerThread.start();
handler = new SumHandler(this, handlerThread.getLooper());
HandlerThread也是一个线程.通过start()启动,里面的Looper就已经初始化好了再调用handler = new SumHandler(this, handlerThread.getLooper()),可以启动Looper,不用再显式启动.这样简化了代码.
源代地址:https://github.com/zhouyang209117/AndroidTutorial/tree/master/Crazy/ch3/HandlerThread
android学习11——Handler,Looper,MessageQueue工作原理的更多相关文章
- Android Native -- Message/Handler/Looper机制(原理篇)
		
⌈Android Native消息队列处理系列文章⌋ Android Native -- Message/Handler/Looper机制(原理篇) Android Native -- Message ...
 - Android Native -- Message/Handler/Looper机制(应用篇)
		
⌈Android Native消息队列处理系列文章⌋ Android Native -- Message/Handler/Looper机制(原理篇) Android Native -- Message ...
 - 讲讲Handler+Looper+MessageQueue 关系
		
Handler+Looper+MessageQueue这三者的关系其实就是Android的消息机制.这块内容相比开发人员都不陌生,在面试中,或者日常开发中都会碰到,今天就来讲这三者的关系. 概述: H ...
 - Android消息机制之ThreadLocal的工作原理
		
来源: http://blog.csdn.net/singwhatiwanna/article/details/48350919 很多人认为Handler的作用是更新UI,这说的的确没错,但是更新UI ...
 - Handler+Looper+MessageQueue深入详解
		
概述:Android中的异步处理机制由四部分组成:Handler+Looper+MessageQueue+message,用于实现线程间的通信. 用到的概念: Handler: 主要作用是发送消息和处 ...
 - Handler Looper MessageQueue 之间的关系
		
Handler Looper MessageQueue 之间的关系 handler在安卓开发中常用于更新界面ui,以及其他在主线程中的操作.内部结构大概图为: 1.handler持有一个Looper对 ...
 - android 消息系统Handler、MessageQueue、Looper源代码学习
		
android消息系统 总体框架如图所看到的 在安卓的消息系统中,每一个线程有一个Looper,Looper中有一个MessageQueue,Handler向这个队列中投递Message,Looper ...
 - 深入源代码解析Android中的Handler,Message,MessageQueue,Looper
		
本文主要是对Handler和消息循环的实现原理进行源代码分析.假设不熟悉Handler能够參见博文< Android中Handler的使用>,里面对Android为何以引入Handler机 ...
 - Android消息机制:Looper,MessageQueue,Message与handler
		
Android消息机制好多人都讲过,但是自己去翻源码的时候才能明白. 今天试着讲一下,因为目标是讲清楚整体逻辑,所以不追究细节. Message是消息机制的核心,所以从Message讲起. 1.Mes ...
 
随机推荐
- MS SQL Server数据库修复/MDF数据文件数据恢复/MDF质疑/mdf无法附加
			
微软的SQL Server 数据库最常用的有两种类型的文件: 1.主要数据文件,文件后缀一般是.MDF: 2.事务日志文件,文件后缀一般是.LDF. 用户数据表.视图.存储过程等等数据,都是存放在MD ...
 - python 错误AttributeError: 'module' object has no attribute 'AF_INET'
			
写了一个简单的python socket的程序.运行时,报错如下 原因:文件的命名与Python的function的命名冲突 修改名称后,发现还是无法运行,检查目录下面是否有 这样子的一个文件,删除即 ...
 - 1833: [ZJOI2010]count 数字计数
			
1833: [ZJOI2010]count 数字计数 Time Limit: 3 Sec Memory Limit: 64 MBSubmit: 2951 Solved: 1307[Submit][ ...
 - max-width
			
#main { max-width: 600px; margin: 0 auto; } <div id="main"> Using max-width instead ...
 - 会话Cookie及session的关系(Cookie & Session)
			
会话Cookie及session的关系(Cookie & Session) 在通常的使用中,我们只知道session信息是存放在服务器端,而cookie是存放在客户端.但服务器如何使用sess ...
 - php常用图片处理类
			
<?php /** * 已知问题:1.在图片缩放功能中,使用imagecreatetruecolor函数创建画布,并使用透明处理算法,但PNG格式的图片无法透明.用imagecreate函数创建 ...
 - Delphi 获取内存及CPU信息的函数
			
Uses MemoryCpuUtils;//首先引用该单元 //声明下列变量用来存储读取的数值 Var iTotalPhysics, iTotalVirtual, iTotalPageFile, iC ...
 - php Excel文件导入  Spreadsheet_Excel_Reader
			
刚刚开通博客,希望能够通过博客的形式记录自己的学习与成长,同时也希望能够和路上的同僚们多交流,共同进步 小白 -> 大神 go! go! go!! 先总结一下前几天写的Excel导入吧,希 ...
 - C# Linq to SQL — Group by
			
需求是需要统计数据库中表某一列的总数量,同时以List的形式返回到UI层. Linq to SQL中的Group by用法如下: IList<Unit.HandleCountClass> ...
 - 常用的.net开源项目
			
Json.NET http://json.codeplex.com/ Json.Net 是一个读写Json效率比较高的.Net框架.Json.Net 使得在.Net环境下使用Json更加简单.通过Li ...