好玩的Handler
- Android提供了Handler和Looper来满足线程间的通信;
- Handler和Activity的任务栈不同,它是先进先出原则;
- Handler:你可以构造Handler对象来与Looper沟通,以便push新消息到MessageQueue里,或者接口Looper从MessageQueue取出的消息;
- Looper类用来管理特定线程内对象之间交换Message;
- 一个线程可以产生一个Looper对象,由他来管理此线程的MessageQueue(消息队列);
- MessageQueue:用来存放线程放入的消息;
- 每一个消息都需要制定的Handler来处理,通过Handler创建消息便可以完成此功能.Android引入了消息池.Handler创建消息时首先查询消息池中是否有消息存在,如果有,则直接取出,如果没有,则重新初始化一个消息实例.
- 使用消息池的好处是:消息不被使用时,并不作为垃圾回收,而是放入消息池中,可供下次Handler创建消息时使用.消息池提高了消息对象的复用,减少系统垃圾回收的次数.Message.obtain()来获取消息,最大数为50;
综上所述:这就是一个标准的的异步操作,就像我们寄信一样,我们只负责写好信(Message)通过邮递员(Handler)放入到邮箱(MessageQueue)中,由工作人员(Looper)去循环查询,再由邮递员处理(Handler)处理这些消息;- 应用场景:两秒后打开一个Activity
- //延迟两秒跳转
newHandler().postDelayed(newRunnable(){@Overridepublicvoid run(){Intent intent=newIntent(MainActivity.this,TestActivity.class);startActivity(intent);}},2000);
- 先来看一个简单的消息吧
- privateProgressBar mProgressBar;
privateint i =0;privateHandler mHandler =newHandler(){ // 创建Handle@Overridepublicvoid handleMessage(Message msg){super.handleMessage(msg);Log.i("-mHandler->",i+"");mProgressBar.setProgress(i);}};privateRunnable runnable =newRunnable(){@Overridepublicvoid run(){Log.i("-Runnable->",i+"");i +=10;// 要做的事情,这里再次调用此Runnable对象,以实现每两秒实现一次的定时器操作mHandler.postDelayed(runnable,2000); // 定时器mHandler.sendMessageDelayed(Message.obtain(),0);// 发送消息才会触发重写的handleMessage方法}};@Overrideprotectedvoid onCreate(@NullableBundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_handler);mProgressBar =(ProgressBar) findViewById(R.id.pb_handler);mHandler.post(runnable);// 开始执行线程// runnable.run(); // 也可以用这个来开始线程}/*** 删除的时候停止线程操作*/@Overrideprotectedvoid onDestroy(){super.onDestroy();mHandler.removeCallbacks(runnable);}}
- 获取Message的两种方法
- // 两种获取Message的方法
// Returns a new Message from the global message pool.mHandler.obtainMessage()和Message.obtain()
- // 两种方法其实是一样的,只不过一个是通过Handler获取,一个是通过Message的静态方法获得,查询Handler的源码会发现,obtainMessage的方法构成:
publicfinalMessage obtainMessage(){returnMessage.obtain(this);}
- 通过查询源码后发现,Message提供了诸如以下的变量
- Message的recycleUnchecked()方法
void recycleUnchecked(){// Mark the message as in use while it remains in the recycled object pool.// Clear out all other details.flags = FLAG_IN_USE; //intwhat =0; // intarg1 =0; // intarg2 =0; // intobj =null; // ObjectreplyTo =null; // Messenger 信使,信差sendingUid =-1;when =0; // longtarget =null; // Handlercallback =null; // Runabledata =null; // Bundlesynchronized(sPoolSync){if(sPoolSize < MAX_POOL_SIZE){next = sPool;sPool =this;sPoolSize++;}}}
使用系统变量的好处是可以大大减少系统的消耗;所以更新进度条的代码应修改为mProgressBar.setProgress(msg.arg1);
- privateRunnable runnable =newRunnable(){
@Overridepublicvoid run(){Log.i("-Runnable->", i +"");i +=3;// 要做的事情,这里再次调用此Runnable对象,以实现每两秒实现一次的定时器操作mHandler.postDelayed(runnable,300);Message msg = mHandler.obtainMessage();msg.arg1 +=i;mHandler.sendMessage(msg);// 发送消息才会触发重写的handleMessage方法// mHandler.sendMessageDelayed(Message.obtain(),0); // 发送消息才会触发重写的handleMessage方法}};
- 重新优化下Handler
- privateHandler mHandler =newHandler(){
@Overridepublicvoid handleMessage(Message msg){super.handleMessage(msg);//Log.i("-mHandler->", i + "");if(msg.arg1 >100){mHandler.removeCallbacks(runnable);}else{mProgressBar.setProgress(msg.arg1);}}};
好玩的Handler的更多相关文章
- android Handler介绍
Handler使用介绍: Handler根据接收的消息,处理UI更新.Thread线程发出消息,通知Handler更新UI. Handler mHandler = new Handler() { p ...
- Handler
1.1 继承AbstractController优点:能定制请求方式 package cn.happyl.controller; import javax.servlet.http.HttpServl ...
- Android消息处理机制(Handler、Looper、MessageQueue与Message)
Android是消息驱动的,实现消息驱动有几个要素: 消息的表示:Message 消息队列:MessageQueue 消息循环,用于循环取出消息进行处理:Looper 消息处理,消息循环从消息队列中取 ...
- Android笔记——Handler Runnable与Thread的区别
在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口:Thread类是在java.lang包中定义的.一个类只要继承了Thread类同时覆写了本类中的run() ...
- Android消息传递之Handler消息机制
前言: 无论是现在所做的项目还是以前的项目中,都会遇见线程之间通信.组件之间通信,目前统一采用EventBus来做处理,在总结学习EventBus之前,觉得还是需要学习总结一下最初的实现方式,也算是不 ...
- Handler系列之内存泄漏
本篇简单的讲一下平常使用Handler时造成内存泄漏的问题. 什么是内存泄漏?大白话讲就是分配出去的内存,回收不回来.严重会导致内存不足OOM.下面来看一下造成内存泄漏的代码: public clas ...
- Handler系列之创建子线程Handler
上一篇我介绍了Handler机制的工作原理,默认情况下,ActivityThread类为我们创建的了主线程的Looper和消息队列,所以当你创建Handler之后发送消息的时候,消息的轮训和handl ...
- Handler系列之原理分析
上一节我们讲解了Handler的基本使用方法,也是平时大家用到的最多的使用方式.那么本节让我们来学习一下Handler的工作原理吧!!! 我们知道Android中我们只能在ui线程(主线程)更新ui信 ...
- Handler系列之使用
作为一个Android开发者,我们肯定熟悉并使用过Handler机制.最常用的使用场景是"在子线程更新ui",实际上我们知道上面的说话是错误的.因为Android中只有主线程才能更 ...
随机推荐
- mysql join 和left join 对于索引的问题
今天遇到一个left join优化的问题,搞了一下午,中间查了不少资料,对MySQL的查询计划还有查询优化有了更进一步的了解,做一个简单的记录: select c.* from hotel_info_ ...
- iOS开发系列--通知与消息机制
概述 在多数移动应用中任何时候都只能有一个应用程序处于活跃状态,如果其他应用此刻发生了一些用户感兴趣的那么通过通知机制就可以告诉用户此时发生的事情.iOS中通知机制又叫消息机制,其包括两类:一类是本地 ...
- 2000条你应知的WPF小姿势 基础篇<15-21>
在正文开始之前需要介绍一个人:Sean Sexton. 来自明尼苏达双城的软件工程师,对C#和WPF有着极深的热情.最为出色的是他维护了两个博客:2,000Things You Should Know ...
- MySQL基础之存储过程
学过之后却没有总结,今天好不容易有点时间来看看. 存储过程的优势 1.简化复杂的SQL语句,将多个SQL语句封装成为一个存储过程,可以在其中加上一些流程控制语句 2.存储过程封装在数据库内部,编译之后 ...
- C#提供APP接口之JSON差异
C#在给APP提供接口,现在返回的数据大部分分为三类:JSON.XML.BTYE. 今天简单说下C#给APP提供接口返回JSON的一些异同: 1.通过Newtonsoft.Json.JsonConve ...
- 10最好用的Node.js工具、插件和资料库
每一个称职的程序员都应该拥有一套极好的工具来提高自己的工作效率.在Livecoding.tv 上,那里的程序员分享了10个他们认为是最好用的工具.插件和资料库.据说,以下的这10个工具是使用Node. ...
- Kafka 文档引言
原文地址:https://kafka.apache.org/documentation.html#semantics 1.开始 1.1 引言 Kafka是一个分布式,分区队列,冗余备份的消息存储服务. ...
- MUI APP关于页面之间的传值,plusready和自定义事件
最近在用MUI开发这个APP,发现有时候这个plusready不起作用,表现在,这个页面如果重复打开,这个plusready就进不去,然后上一个页面传过来的值,就没法接收了.这个经过MUI官方确认,是 ...
- 设计模式(七): 通过转接头来观察"适配器模式"(Adapter Pattern)
在前面一篇博客中介绍了“命令模式”(Command Pattern),今天博客的主题是“适配器模式”(Adapter Pattern).适配器模式用处还是比较多的,如果你对“适配器模式”理解呢,那么自 ...
- CSS3与页面布局学习总结(四)——页面布局大全
一.负边距与浮动布局 1.1.负边距 所谓的负边距就是margin取负值的情况,如margin:-100px,margin:-100%.当一个元素与另一个元素margin取负值时将拉近距离.常见的功能 ...