1. Android提供了Handler和Looper来满足线程间的通信;
  2. Handler和Activity的任务栈不同,它是先进先出原则;
  3. Handler:你可以构造Handler对象来与Looper沟通,以便push新消息到MessageQueue里,或者接口Looper从MessageQueue取出的消息;
  4. Looper类用来管理特定线程内对象之间交换Message;
  5. 一个线程可以产生一个Looper对象,由他来管理此线程的MessageQueue(消息队列);
  6. MessageQueue:用来存放线程放入的消息;
  7. 每一个消息都需要制定的Handler来处理,通过Handler创建消息便可以完成此功能.Android引入了消息池.Handler创建消息时首先查询消息池中是否有消息存在,如果有,则直接取出,如果没有,则重新初始化一个消息实例.
  8. 使用消息池的好处是:消息不被使用时,并不作为垃圾回收,而是放入消息池中,可供下次Handler创建消息时使用.消息池提高了消息对象的复用,减少系统垃圾回收的次数.Message.obtain()来获取消息,最大数为50;
  9.  
  10.  综上所述:这就是一个标准的的异步操作,就像我们寄信一样,我们只负责写好信(Message)通过邮递员(Handler)放入到邮箱(MessageQueue)中,由工作人员(Looper)去循环查询,再由邮递员处理(Handler)处理这些消息;
  11. 应用场景:两秒后打开一个Activity
    1. //延迟两秒跳转
    2. newHandler().postDelayed(newRunnable(){
    3. @Override
    4. publicvoid run(){
    5. Intent intent=newIntent(MainActivity.this,TestActivity.class);
    6. startActivity(intent);
    7. }
    8. },2000);
     
  12. 先来看一个简单的消息吧
    1. privateProgressBar mProgressBar;
    2. privateint i =0;
    3. privateHandler mHandler =newHandler(){ // 创建Handle
    4. @Override
    5. publicvoid handleMessage(Message msg){
    6. super.handleMessage(msg);
    7. Log.i("-mHandler->",i+"");
    8. mProgressBar.setProgress(i);
    9. }
    10. };
    11. privateRunnable runnable =newRunnable(){
    12. @Override
    13. publicvoid run(){
    14. Log.i("-Runnable->",i+"");
    15. i +=10;
    16. // 要做的事情,这里再次调用此Runnable对象,以实现每两秒实现一次的定时器操作
    17. mHandler.postDelayed(runnable,2000); // 定时器
    18. mHandler.sendMessageDelayed(Message.obtain(),0);// 发送消息才会触发重写的handleMessage方法
    19. }
    20. };
    21. @Override
    22. protectedvoid onCreate(@NullableBundle savedInstanceState){
    23. super.onCreate(savedInstanceState);
    24. setContentView(R.layout.activity_handler);
    25. mProgressBar =(ProgressBar) findViewById(R.id.pb_handler);
    26. mHandler.post(runnable);// 开始执行线程
    27. // runnable.run(); // 也可以用这个来开始线程
    28. }
    29. /**
    30. * 删除的时候停止线程操作
    31. */
    32. @Override
    33. protectedvoid onDestroy(){
    34. super.onDestroy();
    35. mHandler.removeCallbacks(runnable);
    36. }
    37. }
     
  13. 获取Message的两种方法
    1. // 两种获取Message的方法
    2. // Returns a new Message from the global message pool.
    3. mHandler.obtainMessage()和Message.obtain() 
    1. // 两种方法其实是一样的,只不过一个是通过Handler获取,一个是通过Message的静态方法获得,查询Handler的源码会发现,obtainMessage的方法构成:
    2. publicfinalMessage obtainMessage()
    3. {
    4. returnMessage.obtain(this);
    5. }
  14. 通过查询源码后发现,Message提供了诸如以下的变量
    1. Message的recycleUnchecked()方法
    2. void recycleUnchecked(){
    3. // Mark the message as in use while it remains in the recycled object pool.
    4. // Clear out all other details.
    5. flags = FLAG_IN_USE; //int
    6. what =0; // int
    7. arg1 =0; // int
    8. arg2 =0; // int
    9. obj =null; // Object
    10. replyTo =null; // Messenger 信使,信差
    11. sendingUid =-1;
    12. when =0; // long
    13. target =null; // Handler
    14. callback =null; // Runable
    15. data =null; // Bundle
    16. synchronized(sPoolSync){
    17. if(sPoolSize < MAX_POOL_SIZE){
    18. next = sPool;
    19. sPool =this;
    20. sPoolSize++;
    21. }
    22. }
    23. }
    使用系统变量的好处是可以大大减少系统的消耗;所以更新进度条的代码应修改为
    1. mProgressBar.setProgress(msg.arg1);
    1. privateRunnable runnable =newRunnable(){
    2. @Override
    3. publicvoid run(){
    4. Log.i("-Runnable->", i +"");
    5. i +=3;
    6. // 要做的事情,这里再次调用此Runnable对象,以实现每两秒实现一次的定时器操作
    7. mHandler.postDelayed(runnable,300);
    8. Message msg = mHandler.obtainMessage();
    9. msg.arg1 +=i;
    10. mHandler.sendMessage(msg);// 发送消息才会触发重写的handleMessage方法
    11. // mHandler.sendMessageDelayed(Message.obtain(),0); // 发送消息才会触发重写的handleMessage方法
    12. }
    13. };
     
  15. 重新优化下Handler
    1. privateHandler mHandler =newHandler(){
    2. @Override
    3. publicvoid handleMessage(Message msg){
    4. super.handleMessage(msg);
    5. //Log.i("-mHandler->", i + "");
    6. if(msg.arg1 >100){
    7. mHandler.removeCallbacks(runnable);
    8. }else{
    9. mProgressBar.setProgress(msg.arg1);
    10. }
    11. }
    12. };
     

好玩的Handler的更多相关文章

  1. android Handler介绍

    Handler使用介绍: Handler根据接收的消息,处理UI更新.Thread线程发出消息,通知Handler更新UI. Handler mHandler = new Handler() {  p ...

  2. Handler

    1.1 继承AbstractController优点:能定制请求方式 package cn.happyl.controller; import javax.servlet.http.HttpServl ...

  3. Android消息处理机制(Handler、Looper、MessageQueue与Message)

    Android是消息驱动的,实现消息驱动有几个要素: 消息的表示:Message 消息队列:MessageQueue 消息循环,用于循环取出消息进行处理:Looper 消息处理,消息循环从消息队列中取 ...

  4. Android笔记——Handler Runnable与Thread的区别

    在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口:Thread类是在java.lang包中定义的.一个类只要继承了Thread类同时覆写了本类中的run() ...

  5. Android消息传递之Handler消息机制

    前言: 无论是现在所做的项目还是以前的项目中,都会遇见线程之间通信.组件之间通信,目前统一采用EventBus来做处理,在总结学习EventBus之前,觉得还是需要学习总结一下最初的实现方式,也算是不 ...

  6. Handler系列之内存泄漏

    本篇简单的讲一下平常使用Handler时造成内存泄漏的问题. 什么是内存泄漏?大白话讲就是分配出去的内存,回收不回来.严重会导致内存不足OOM.下面来看一下造成内存泄漏的代码: public clas ...

  7. Handler系列之创建子线程Handler

    上一篇我介绍了Handler机制的工作原理,默认情况下,ActivityThread类为我们创建的了主线程的Looper和消息队列,所以当你创建Handler之后发送消息的时候,消息的轮训和handl ...

  8. Handler系列之原理分析

    上一节我们讲解了Handler的基本使用方法,也是平时大家用到的最多的使用方式.那么本节让我们来学习一下Handler的工作原理吧!!! 我们知道Android中我们只能在ui线程(主线程)更新ui信 ...

  9. Handler系列之使用

    作为一个Android开发者,我们肯定熟悉并使用过Handler机制.最常用的使用场景是"在子线程更新ui",实际上我们知道上面的说话是错误的.因为Android中只有主线程才能更 ...

随机推荐

  1. Xamarin和微软发起.NET基金会

    新闻<微软宣布成立.NET基金会全面支持开源项目 包括C#编译器Roslyn>,看到大家对微软的开放都很兴奋.在此之前在.NET社区也有了大量的开源项目,所列的24个项目也是早就开源,这次 ...

  2. Ubuntu Server(Ubuntu 14.04 LTS 64位)安装libgdiplus2.10.9出错问题记录

    首先下载libgdiplus2.10.9安装包 wget http://download.mono-project.com/sources/libgdiplus/libgdiplus-2.10.9.t ...

  3. 快速web开发中的前后端框架选型最佳实践

    这个最佳实践是我目前人在做的一个站点,主要功能: oauth登录 发布文章(我称为"片段"),片段可以自定义一些和内容有关的指标,如“文中人物:12”.支持自定义排版.插图.建立相 ...

  4. Hbase学习笔记01

    最近做项目接触到了HDFS.mapreduce以及Hbase,有了实战机会,今天打算将这些知识好好总结下,以备不时之需.首先从Hbase开始吧. Hbase是建立在HDFS上的分布式数据库,下图是Hb ...

  5. (转) [it-ebooks]电子书列表

    [it-ebooks]电子书列表   [2014]: Learning Objective-C by Developing iPhone Games || Leverage Xcode and Obj ...

  6. Entity Framework 6 Recipes 2nd Edition(12-1)译 -> 当SaveChanges( ) 被调用时执行你的代码

    第12章定制EF 在本章的小节里,定制实体对象和EF处理的一些功能.这些小节将涵盖很多”幕后”的事情,能让你的代码更加统一解决一些事情,比如用一个业务规则中心统一地为实体执行验证. 本章开始的小节,将 ...

  7. java终端获取输入

    上一篇博客已经介绍了System.in这个输入流这次谈谈java如何获取终端(控制台)的输入 (1)BufferedReader JDK 1.4 及以下的版本中要想从控制台中输入数据只有一种办法,即使 ...

  8. angular + easyui 做界面验证

    angular结合easyui这事其实并不是很合适,因为:angular的特点之一是双向绑定,页面元素与页面逻辑之间解耦:easyui是对页面元素进行封装,甚至一些组件是隐藏了原本的dom元素,初始化 ...

  9. WebGIS中快速整合管理多源矢量服务以及服务权限控制的一种设计思路

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 在真实项目中,往往GIS服务数据源被其他多个信息中心或者第三方 ...

  10. 详解web容器 - Jetty与Tomcat孰强孰弱

    Jetty 基本架构 Jetty目前的是一个比较被看好的 Servlet 引擎,它的架构比较简单,也是一个可扩展性和非常灵活的应用服务器.它有一个基本数据模型,这个数据模型就是 Handler(处理器 ...